2009-10-09 6 views
1

몇 가지 subselect를 사용하여 약간의 불쾌한 쿼리가 발생하여 실제로 속도가 느려집니다. 이미 쿼리를 캐싱 중이지만 그 결과가 자주 변경되며 쿼리 결과는 트래픽이 많은 페이지에 표시됩니다.어떻게이 쿼리를 최적화 할 수 있습니까?

SELECT user_id, user_id AS uid, (SELECT correct_words 
           FROM score 
           WHERE user_id = `uid` 
           ORDER BY correct_words DESC, incorrect_words ASC 
           LIMIT 0, 1) AS correct_words, 
           (SELECT incorrect_words 
           FROM score 
           WHERE user_id = `uid` 
           ORDER BY correct_words DESC, incorrect_words ASC 
           LIMIT 0, 1) AS incorrect_words 
FROM score 
WHERE user_id > 0 
AND DATE(date_tested) = DATE(NOW()) 
GROUP BY user_id 
ORDER BY correct_words DESC,incorrect_words ASC 
LIMIT 0,7 

쿼리의 목적은 그 날에 대한 사용자의 최고 점수를 골라 있지만 대신에 따라서 자신의 점수 (모두의 사용자의 가장 높은 점수 인스턴스를 보여, 예를 들어, 경우에 하나의 사용자 실제로 그 날의 상위 10 점 중 4 점을 얻었습니다. 사용자의 최고 점수 만 표시하고 나머지는 삭제하고 싶습니다.)

시도해 보았으나 나는이 쿼리의 결과를 다른 방식으로 복제하지 않았습니다. 현재 평균 실행 시간은 약 2 초이지만 표가 커질수록 크게 늘어날 수 있습니다.

의견이 있으십니까?

+0

표 정의 및 색인을 표시하십시오. – Asaph

+0

먼저 잘못된 형식으로 자신과 우리를 대면하지 마십시오. 나는 당신의 질의를 다시 읽을 수 있도록 다시 포맷했다. 연산자 주위의 공백을 사용하고 쉼표 뒤에 각 SQL 문에 대해 새 행을 사용하십시오. – markus

답변

2

이 시도. MySQL에서 그룹화 할 때, 그룹화되지 않은 컬럼은 FIRST (컬럼)에 해당하는 값을 반환합니다. 첫 번째 발생 값입니다.

SELECT user_id, correct_words, incorrect_words 
FROM 
(SELECT user_id, correct_words, incorrect_words 
    FROM score 
    WHERE user_id>0 
    AND DATE(date_tested)=DATE(NOW()) 
    ORDER BY correct_words DESC,incorrect_words ASC 
) 
GROUP BY user_id 
LIMIT 0,7 
+0

분명히 투표 할 수는 없지만 훌륭하게 작동했습니다 :) .2 평균적으로 실행 시간이 매우 일관되게 –

1

correct_wordsincorrect_words에 대한 하위 쿼리가 실제로 성능을 저하시킬 수 있습니다. 최악의 경우, MySQL은 고려하는 각 행에 대해 이러한 쿼리를 실행해야합니다 (반환하는 각 행이 아님). 스칼라 하위 쿼리를 사용하는 대신 JOIN -variants를 적절하게 사용하도록 쿼리를 다시 작성하십시오.

또한 DATE(date_tested)=DATE(NOW())으로 필터링하면 MySQL이 색인을 사용하지 못할 수 있습니다. 필자는 MySQL의 프로덕션 버전에서 기능 기반 인덱스를 허용하지 않는다고 생각합니다.

필터링하고 정렬하는 모든 열에 인덱스가 있는지 확인하십시오. 필터링되거나 정렬 된 열이 쿼리와 일치하면 MySQL은 다중 열 인덱스를 사용할 수 있습니다. CREATE INDEX score_correct_incorrect_idx ON score (correct_words DESC, incorrect_words ASC);은 후보 인덱스가 될 것이지만, MySQL이 생성 한 실행 계획과 테이블 크기 추정치에 따라 MySQL을 사용하지 않을 수도 있습니다.

하위 쿼리는 기본적으로 올바른 순서에있는 모든 점수의 결과 집합을 반환하고, 외부 쿼리를 선두을 greps :

+0

인덱스가 확실히 도움이되었습니다 - 감사합니다 –

관련 문제