2010-01-18 3 views
0

통계를 컴파일하기 위해 매일 쿼리를 실행하고 있지만 실제로 비효율적 인 것처럼 보입니다. 쿼리입니다 :Mysql Sub Select Query Optimization

SELECT a.id, tstamp, label_id, (SELECT author_id FROM b WHERE b.tid = a.id ORDER BY b.tstamp DESC LIMIT 1) AS author_id 
FROM a, b 
WHERE (status = '2' OR status = '3') 
AND category != 6 
AND a.id = b.tid 
AND (b.type = 'C' OR b.type = 'R') 
AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end} 
ORDER BY b.tstamp DESC 
LIMIT 500 

이 쿼리는 정말 느리게 실행되는 것 같습니다. 쓰레기 명명에 대한 사과 - 나는 실제 테이블 이름을 공개하지 말 것을 요청 받았다.

하위 선택이있는 이유는 외부 선택이 표 a에서 한 행을 가져와 표 b에서 한 행을 가져 오기 때문입니다. 그러나 또한 테이블 b에서 최신 author_id를 알아야하기 때문에 subselect를 실행하여 리턴하십시오. PHP 루프 내부에서 다른 select를 실행하고 싶지 않습니다. 비효율적이기도합니다.

올바르게 작동합니다.이 데이터 세트를 얻는 훨씬 더 빠른 방법을 찾아야합니다.

+0

@Matt : 제공된 답변을 시도해보고 도움을 받아야하며 문제를 해결 한 대답을 받아 들여야합니다. 아무도하지 않았다면 질문을 편집하여 더 많은 정보를 제공하십시오. –

답변

2

b.tstamp 경우, OMG 조랑말 '솔루션을.

그렇지 않으면이 솔루션을 시도해 볼 수 있습니다. 전체 결과를 b.tstamp DESC으로 정렬하고 author_id 당 순위를 추가합니다. 외부 선택은 인 행만 취합니다. tstampauthor_id 인 행입니다.

SELECT id, tstamp, label_id, author_id 
    FROM (SELECT id, 
       tstamp, 
       label_id, 
       author_id, 
       CASE 
       WHEN @author_id != author_id THEN @row_num := 1 
       ELSE @row_num := @row_num + 1 
       END AS rank, 
       @author_id := b.author_id 
      FROM a, 
       b, 
       (SELECT @row_num := 0, @author_id := NULL) y 
      WHERE a.id = b.tid 
      AND (status = '2' OR status = '3') 
      AND category != 6 
      AND (b.type = 'C' OR b.type = 'R') 
      AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end} 
      ORDER BY b.author_id, b.tstamp DESC 
) x 
WHERE x.rank = 1 
LIMIT 500 

아직 해결되지 않았다면 의견을 말하십시오.

2

시도 : b.tid 내에서 고유

SELECT a.id, 
     b.tstamp, 
     label_id, 
     y.author_id 
    FROM TABLE_A a 
    JOIN TABLE_B b ON b.tid = a.id 
    JOIN (SELECT b.tid, 
       MAX(b.tstamp) 'm_tstamp' 
      FROM TABLE_B b 
     GROUP BY b.tid) x ON x.tid = a.id 
    JOIN (SELECT b.tid, 
       b.author_id, 
       b.tstamp 
      FROM TABLE_B b 
     GROUP BY b.tid) y ON y.tid = a.id 
         AND y.tstamp = x.m_tstamp 
    WHERE status IN ('2', '3') 
    AND b.type IN ('C', 'R') 
    AND category != 6 
    AND a.tstamp1 BETWEEN {$timestamp_start} AND {$timestamp_end} 
ORDER BY b.tstamp DESC 
    LIMIT 500 
+0

@Peter Lang : 감사합니다! 수정 됨. –