2010-01-22 7 views
4

이것은 내가 (관련이없는 일부 조인하지 않고 그)를 수행하고있어 질의입니다 .MySQL의 그룹은

문제는 GROUP BY에 성능 문제가 있습니다 (GROUP BY를 사용하지 않는 것보다 10 배 이상 소요됨). "a"에서 각 멤버의 한 행만 가져와야합니다.

어떻게하면 더 빨리 만들 수 있습니까?

편집 : a.id 및/또는 c.id.로 필터링 할 수 있어야합니다. 내가 얻고있는 결과 세트는 "a"의 "유효한"멤버 당 단 하나의 행, 즉 제약 조건과 일치하는 행을 의미합니다. 필터와 일치하지 않는 행은 반환되지 않습니다.

SELECT a.*, c.id 
FROM a 
LEFT OUTER JOIN b ON a.id = b.id_anunciante 
LEFT OUTER JOIN c ON c.id = b.id_rubro 
WHERE c.id = 1 
OR a.id = 1 
GROUP BY a.id 

a.id, b.id_anunciante, b.id_rubro, c.id 모든 인덱스입니다 은 내 원래의 쿼리에서이이 방법을 수행 할 수있다.

답변

5
SELECT a.*, 
     (
     SELECT c.id 
     FROM b 
     JOIN с 
     ON  c.id = b.id_rubro 
     WHERE b.id_anunciante = a.id 
     -- add the ORDER BY condition to define which row will be selected. 
     LIMIT 1 
     ) 
FROM a 

더 빠르게 작동하려면 b (id_anunciante)에 색인을 생성하십시오.

업데이트 :

당신은 여기 OUTER JOINs 필요가 없습니다.

이 같은 조회를 다시 작성

:

SELECT a.*, c.id 
FROM a 
JOIN b 
ON  b.id_anunciante = a.id 
JOIN c 
ON  c.id = b.id_rubro 
WHERE a.id = 1 
UNION ALL 
SELECT a.*, 1 
FROM a 
WHERE EXISTS 
     (
     SELECT NULL 
     FROM c 
     JOIN b 
     ON  b.id_rubro = c.id 
     WHERE c.id = 1 
       AND b.id_anunciante = a.id 
     ) 
+0

답변 해 주셔서 감사합니다. c.id 및/또는 a.id로 필터링해야하는 경우 어떻게해야합니까? 나는 그렇게 할 수 없다. 그렇지? – Gerardo

+0

'@ macaco' : 할 수 있어요. 'a'를 걸러 내기 위해 바깥 쪽 질의에'WHERE' 조건을 추가하고'c'를 걸러내는 하위 질의에 조건을 추가하십시오. – Quassnoi

+0

하위 쿼리 "c.id에서 b.id_anunciante = a.id 및 c.id = 1"로 c.id 필터링 시도했지만 행과 하위 쿼리 열이 채워져 있어야합니다 같은 양의 있어요 NULL과 함께. – Gerardo

0

피해야 할 ORDER BY NULL 추가 암시 MySQL을하여 그룹을하고 않을 때 정렬.

당신은 a.id, b.id_anunciante, b.id_rubro 및 c.id에 색인/PK가 있다고 가정합니까? 귀하의 MySQL 버전이 색인 병합을 수행 할 수없는 경우 b.id_anunciante, b.id_rubro에 복합 색인을 추가 할 수 있습니다.