2013-05-07 2 views
2

느린 쿼리에 문제가 있습니다. 테이블을 고려해보십시오. - VoterGuid, CandidateGuid의 두 개의 열이 있습니다. 유권자가 여러 후보자에게 투표를 실시합니다.매우 느린 SQL 쿼리

이 테이블에는 300 만 개가 넘는 행이 있습니다. 약 13,000 명의 유권자가 약 270 만 개의 별개 후보로 투표합니다. 테이블의 총 행 수는 현재 650 만 개입니다.

내 쿼리에서 얻으려고하는 것은 가능한 가장 빠르고 캐시 효율적인 방법입니다 (우리는 SQL Express를 사용하고 있습니다) -받은 투표 수에 따라 상위 1000 명의 후보가됩니다.

SELECT CandidateGuid, COUNT(*) CountOfVotes 
FROM dbo.tblVotes 
GROUP BY CandidateGuid 
HAVING COUNT(*) > 1 
ORDER BY CountOfVotes DESC 

... 그러나 이것은 아주 전체 테이블이있는 경우 SQL 익스프레스에서 실행하는 무섭게 시간이 오래 걸리는 :

코드입니다.

누구나이 속도를 높이고 빠른 시일 내에 실행할 수있는 좋은 방법을 제안 할 수 있습니까? CandidateGuid는 개별적으로 색인이 생성되며, CandidateGuid + VoterGuid에는 복합 기본 키가 있습니다.

+0

나는 당신이 주문을 처리하고 카운트를 평가하기 때문에 CountOfVotes에 추가 인덱스가 필요하다고 생각합니다. – DrCopyPaste

+0

CountOfVotes가이 쿼리 내에서 계산되었지만 영구 인덱스 가능 열이 아닙니다. – Jackfruit

+0

오, 내 늦게 도착하는 것은 너무 미안하다. :) – DrCopyPaste

답변

0

테이블에 두 개의 열만있는 경우이 두 필드의 "일반"색인은 실제로는 전체 테이블의 복사본이므로 주문한 것이므로 많은 도움이되지 않습니다. 인덱스가 전혀 사용되지 않으면 실행 계획을 먼저 확인하십시오. 그런 다음 인덱스를 클러스터형 인덱스로 변경하십시오.

0

대신 HAVING 절에, 최고 N을 사용하여 시도 -과 같이 :이 경우 SQL Server가이 쿼리 속도를 복합 인덱스를 사용 할 수 있는지 모르겠다

SELECT TOP 1000 CandidateGuid, COUNT(*) CountOfVotes 
FROM dbo.tblVotes 
GROUP BY CandidateGuid 
ORDER BY CountOfVotes DESC 
+1

이런 식으로, 'ORDER BY'는 상위 1000 개에없는 항목을 삭제할 수 있습니다. 실제로 원래 HAVING은 불필요합니다. 여기에 조인이 없기 때문에 카운트가 0 인 후보는 단순히 결과에 나타나지 않습니다. –

+0

엔진이 여전히 각 그룹에 대해 COUNT 개의 컴퓨터를 가지고 있지 않습니까? –

0

하지만, 쿼리를 SELECT CandidateGUID, COUNT(VoterGUID) FROM . . .으로 표현해야 최적화가 가능합니다. 이것은 VoterGUID가 PRIMARY KEY의 일부이기 때문에 NULL이 아닌 것을 알기 때문에 "안전"합니다.

복합 기본 키가 (CandidateGUID, VoterGUID)로 지정된 경우 CandidateGUID에서만 별도의 색인을 추가로 사용하지 않아도됩니다. 기존 색인을 사용하여 단일 색인이 도움이 될 검색어를 최적화 할 수 있습니다.