2014-05-21 4 views
0

이의 내가 두 개의 테이블이있는 온라인 포럼 MySQL 데이터베이스를 가지고 있다고 가정 해 봅시다 , 당신이 기대했던대로.가 MAX에 테이블이 다른 테이블에서 레코드 가입

나는 (어떤 메시지가없는 경우, 또는 아무것도에 가입)의 가장 최근에 생성 된 메시지 기록에 대한 모든 주제 기록 LEFT JOIN'ed의 목록을 좀하고 싶습니다

. 결과에서 두 레코드의 모든 필드가 필요합니다.

제가 수행 한 작업은 하위 쿼리를 사용하여 가장 최근에 생성 된 모든 메시지의 테이블을 만든 다음 주제 테이블에 가입시키는 것입니다. 그러나 주제 테이블에 수천 개의 행이 있고 메시지 테이블에 수십만 개의 테이블이있는 경우 정말 어려움을 겪습니다.

성능을 고려하여이 문제를 해결하는 올바른 방법은 무엇입니까?

+0

어떤 DBMS를 사용하고 있습니까? 포스트그레스? 신탁? –

답변

1

이 시도 :

SELECT t.*, m.* 
FROM topic t 
LEFT JOIN 
    (SELECT id_topic, MAX(created) AS created 
    FROM message 
    GROUP BY id_topic 
    ) T2 ON t.id = T2.id_topic 
LEFT JOIN message m ON m.id_topic = T2.id_topic AND m.created = T2.created 

설명 :

첫째, 우리는 각 id_topic 생성 최대 값을 갖는 임시 테이블과 테이블 항목을 가입하고 있습니다. 그런 다음 테이블 메시지가 동일한 임시 테이블과 조인됩니다. 그런 다음 두 테이블에서 결과를 가져옵니다.

+0

감사합니다. Raging Bull. 하위 쿼리가 필요하다는 것을 확인하는 것으로 간주합니다. 아마도 내가보고있는 느린 속도는 다른 곳에서 발생했을 것입니다 (MySQL 5.5). 내가 만든 id_topic + 조인 느껴 조금 "서투른"하지만 다른 접근 방식 중 하나를 모르겠다. 동일한 id_topic + 생성 된 타임 스탬프 (놀랍게도 자주 발생하는)가있는 두 개의 메시지는 두 번째 조인에 의해 선택되어 결과에 중복 행을 생성합니다. 미래에 내 주제 테이블에 "id_message_newest"열을 추가하고 유지 관리 할 수 ​​있습니다 , 그리고 내 SQL 단순화. –

0

이렇게해야합니다. 좋은 성능을 가져야합니다
(message 테이블의 색인이 올바르게 제공되어야합니다).

SELECT t.*, m3.* 
FROM 
topic t 
LEFT JOIN 
(
    SELECT m1.id_topic, max(m1.id) id 
    FROM 
    message m1 
    GROUP BY m1.id_topic 
) m2 ON t.id = m2.id_topic 
LEFT JOIN message m3 ON m2.id = m3.id 
+0

인덱스에 대한 흥미로운 점; 아마도 그게 성능이 타격을 입는 곳입니다. id (unique, both 테이블), id_topic, created 및 id_topic + (하위 쿼리 용)에 대해 인덱스를 설정했지만 어쩌면 내가 놓친 것일 수 있습니다. 나는 단지 이런 종류의 귀걸이를 만들뿐입니다. –

+0

id_topic (첫 번째)과 그 다음 id 테이블 메시지에 대한 색인 추가를 시도하십시오. – Kickstart

관련 문제