2011-09-07 3 views
5

은 먼저, 나는 모든 26,000 행을 선택이 SQL 성능 차이를 고려, 두 번째에, 난 그냥 처음 5거대한 성능 딥

SELECT tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.[timestamp] 

을 원하는
SELECT TOP (5) tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.[timestamp] 

Without: CPU = 201 | Reads: 6880 | Writes: 0 | Duration: 451 
With: CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188 

이것은 단지 나에게 이해가되지 않습니다.이 문제를 해결할 다른 방법이 있습니까?

Martin이 제안한 REBUILD STATISTICS가 관련된 모든 테이블에서 제안 된 후 약간 개선되었지만 TOP 금액을 매개 변수로 변경하는 트릭이 가장 효과적입니다. 통계 전에

재 구축 : 통계 후

CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188 

재 구축 :

DECLARE @TOP INT; SET @TOP=5; 
SELECT TOP (@TOP) tw.* 
FROM entity e 
JOIN entity_tag et on et.entity_id = e.id 
JOIN tag t on t.tag_id = et.tag_id 
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id 
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID 
WHERE e.id = 765131 
ORDER BY tw.timestamp desc 
: 매개 변수

CPU = 218 | Reads: 6899 | Writes: 0 | Duration: 83 

검색어 : 매개 변수와

CPU = 127734 | Reads: 4100436 | Writes: 2656 | Duration: 16880 

Entity Framework를 사용하는 사람들을위한 마지막 발언이 하나 있습니다. 나는 꽤 아니라는 것을 알고

.Take(100).ToList().Take(5) 

을, 그러나 당신이 엔티티 프레임 워크를 사용하는 경우 올바른 실행 계획을 실행할 수있는 유일한 방법 :이 문제가 발생할 경우, 다음과 같이 동일한 매개 변수 기반 동작을 시뮬레이션 할 수 있습니다 내가 말할 수있는 한.

Martin을 올바른 방향으로 가르쳐 주셔서 감사합니다.

+0

성능이 좋지 않은 쿼리의 실행 계획을 가져와야합니다 (이전/이후 비교할 것이 바람직 함). – Justin

+3

흥미 롭습니다. 계획을 게시하십시오. 나는'TOP 5'가 다른 하나의 중첩 된 루프를 가질 수 있다고 생각하니? 또한'DECLARE @TOP INT; SET @ TOP = 5; TOP (@TOP) 선택 ... ' –

+0

답변을 martin으로 게시하십시오 :) 어딘가 암시 적 변환을 수행해야합니다 ... 그건 그냥 미친 짓입니다. 감사! – NKCSS

답변

3

SQL Server 계획이 "처음 5 행 전용"경우를 최적화하기로 선택한 이유가 일부 최적의 경우라고 생각하는 의견이 있습니다. 해시 조인과 같은 조인 루프 조인이 아닌 중첩 루프 조인과 같은 비 블로킹 연산자를 사용할 것입니다.

실행 계획을 게시 할 수 없으므로 두 가지 버전의 계획에 대한 계획을 비교하고 문제 쿼리에 대한 실제 실행 계획에서 실제 행과 예상 행 수를 비교하는 이유를 정확히 알기는 어렵습니다. 문제에 대해 약간의 조명을 설정해야합니다.

컴파일러에서 옵티 마이저의 TOP 5 정보를 숨기면 원하는 계획을 세우기에 충분합니다.