2011-01-20 5 views
3

클러스터되지 않은 키를 통해 레코드를 선택해야하는 큰 테이블이 SQL Server 2005에 있는데 최선을 다해이 프로세스를 최적화하려고합니다.일관되지 않은 SQL Server 실행 계획 키 조회

테이블에 많은 열이 있고 세 개의 다른 열에 클러스터되지 않은 인덱스를 추가했습니다.

SELECT * FROM table WHERE Field1 = 10; 
SELECT * FROM table WHERE Field2 = 40; 
SELECT * FROM table WHERE Field3 = 'A'; 

Field1과 Field2는 정수 필드이고 Field3은 varchar입니다.

SELECT -> Nested Loop -> Index Seek 
         -> Key Lookup 

하지만 그 실행 시간이 크게 일치하지 않는 것을 발견 : 나는이 세 가지 쿼리에 대한 SQL 서버에서 예상 쿼리 실행 계획을 요청하면

, 나는 각각에 대해 기본적으로 같은 계획을 얻을. 특히 두 번째 쿼리는 전체 쿼리 비용의 98 %를 차지합니다. Key Lookup 단계의 비용이 Index Seek에 비해 100 %라는 점을 제외하면 실행 계획은 다른 항목과 동일합니다. 다른 두 쿼리에서는 50 %에 가깝습니다.

키 조회가 바람직하지 않으며 여분의 열을 조회 할 필요가 없도록 인덱스에 열을 추가하여 피할 수 있음을 알고 있습니다. 그러나이 경우 테이블의 모든 열을 반환해야 인덱스에 모두 추가하는 것이 좋습니다. 그러나 어떻게 하나의 색인으로 인해 Key Lookup 작업이 다른 Key Lookup보다 오래 걸릴 수 있습니까?

답변

1

하지만 어떻게 하나 개의 인덱스는 키 조회 작업이 다른 키 조회보다 훨씬 길어질 수 있을까?

모두 예상 키 길이의 현재 통계에 따라 다릅니다.

쿼리 최적화 도구 (QO)은 인덱스에 대한 통계를 조사하여 작동합니다.Fieldb의 인덱스는 평균 카디널리티가 100이지만 다른 필드의 인덱스는 평균 카디널리티가 10000 (100 배 특정) 일 수 있습니다. 따라서 이는 averaged 계획에 근거한 상대적인 표시를 제공합니다.

세부 사항을 보려면 항상 통계 *를 켜십시오. 그러나 실제로는 특정 값의 actual execution time 만 제공합니다. 접근 변수가 무작위 인 경우 QO는 장기간에 걸쳐 더 정확할 수 있습니다.

SELECT * FROM table WHERE Field2 = 40; 
SELECT * FROM table WHERE Field2 = 42; 

이의이 가설 (42)가 모든 레코드의 80 %에 사용되는 특수 코드라고하자이 두 쿼리의 경우를 생각해 보자. 40은 하나의 레코드에서만 사용되는 고유 한 코드입니다. QO가 각각에 대해 서로 다른 예상 행을 표시 할 것으로 기대할 수는 없습니까? 그러나 쿼리를 실행 한 경우 매개 변수화/계획 캐싱이 관련되어 있지 않으면 두 번째 패브릭은 clustered index을 사용하여 80 % (비싼) 책갈피 조회를 수행하는 대신 테이블을 스캔 할 수 있습니다.

*

set statistics io on 
set statistics time on 
보고 통계를 켭니다
0

"쿼리 비용 (배치 대비)"비율이 가장 낮은 것으로 오해 할 수있는 경우가 여러 번 있습니다.

io 및 시간 통계와 함께 실제 실행 계획을보고 실제 상황을 이해하는 것이 좋습니다. 논리는 읽기 CPU 시간과 경과 시간은 각 쿼리에 대해 반환에

set statistics io on 
set statistics time on 

SELECT * FROM table WHERE Field1 = 10; 
SELECT * FROM table WHERE Field2 = 40; 
SELECT * FROM table WHERE Field3 = 'A'; 

그런 다음 보인다.

2

비용은 반드시 시간과 관련이있는 것이 아니라 대신 자원 소비와 더 관련됩니다. 자신의 경우 쿼리를 보지 않고, 테이블 구조를 알고, 열에 포함 된 데이터 구성을 보지 않고 실제로 무슨 일이 벌어지고 있는지 말하기는 어렵습니다. 그러나 조건에 일치하는 레코드 수는 서로 다른 쿼리 계획의 비용을 변화시킬 수 있습니다.

테이블의 색인 생성과 관련하여 색인에 가능한 많은 기준 열을 포함 할 수 있다면 더 편할 수 있습니다. 데이터에 따라 가장 선택적인 열 (가장 많은 데이터를 제거 할 가능성이 높은 열)을 인덱싱하여 더 나은 결과를 얻을 수 있습니다. (그러나 반드시 그렇지는 않습니다. 특히 다른 테이블과 조인하고 결과를 정렬하는 등) 필요하거나 유익한 다른 열을 추가 할 수 있습니다. 색인 생성시 "include"절을 사용하여 덜 선택적 인 "where"열을 색인에 추가하여 필요한 키 조회 수를 줄일 수 있습니다.