2011-08-23 3 views
2

컨텍스트 : SQL Server 2008. 내부 조인에 2 개의 테이블이 있습니다. 4 천만 개의 행이있는 팩트 테이블에는 환자 키와 관리되는 약물 및 기타 사실이 들어 있습니다. 약물 키와 환자 키를이 순서로 결합한 고유 색인 (비 클러스터)이 있습니다. 차원 테이블은 약물 목록 (70 행)입니다. 가입은 약물 키 (대리 키)를 기반으로 약물 코드 (비즈니스 코드)를 얻는 것입니다. 쿼리 :SQL Server 쿼리의 이상한 실행 계획

SELECT a.PKey, a.SomeFact, b.MCode 
FROM tblFact a 
JOIN tblDIM b ON a.MKey = b.MKey 

반환되는 모든 열은 정수입니다. 위의 쿼리는 7 분 내에 실행되며 실행 계획에 (MKey, PKey)의 인덱스가 사용 된 것으로 표시됩니다. 색인은 실행 직전에 재구성되었습니다. 팩트 테이블에서 인덱스를 사용하지 않도록 설정하거나 같은 구조의 인덱스가없는 새 테이블에 데이터를 복사하면 동일한 쿼리에 단 1 분 40 분이 걸립니다.

입학 통계 또한 놀랍습니다.

인덱스 포함 : 테이블 'tblFACT'. 스캔 횟수 70, 논리적 읽기 190296338, 물리적 읽기 685138, 미리 읽기 98713

색인 없음 : 테이블 'tblFACT_copy'. 스캔 횟수 17, 논리적 읽기 468891, 물리적 읽기 0, 미리 읽기 419768

질문 : 왜 인덱스를 사용하여 비효율적 인 경로를 사용하려고합니까?

+1

인덱스 정의와 실행 계획을 볼 수 있습니까? 색인으로 RID_LOOKUP을 수행해야합니까? –

답변

0

드문 경우이지만 데이터베이스가 잘못된 실행 계획을 선택합니다. 이 경우 인덱스는 조인에 사용되지만 모든 데이터가 두 테이블에서 모두 페치되므로 전체 테이블을 스캔하는 것이 더 빠릅니다. WHERE 절을 쿼리에 추가하면 인덱싱 된 버전이 훨씬 빠릅니다. 인덱스가 없으면 필요로하는 레코드 몇 개를 포착하는 대신 전체 테이블을 스캔해야하기 때문입니다.

데이터베이스가 인덱스를 사용하지 않거나 다른 인덱스를 사용하도록 유도하는 지시문이있을 수 있지만 SQL 서버는 잘 모릅니다.

+0

YourTable WITH (INDEX (0))은 테이블 스캔을 수행한다. – Andomar

+0

@Andomar : 멋진 트릭 – vuht2000

+0

그리고 SQL Server 2008 R2 SP1 및 Denali에서는 'FORCESCAN'을 사용하여 모든 색인 스캔을 강제 할 수 있습니다. 유용 할 정도로 많은 비 학술적 사례가 의심 스럽지만. 당신의 억양에 따라 붐비는 프리젠 테이션 홀에서 큰소리로 말을하는 것도 유머러스 할 수 있습니다. :-) http://sqlblog.com/blogs/aaron_bertrand/archive/2011/04/22/sql-server-2008-r2-sp1-ctp-is-now-available.aspx 및 http : // msdn을 참조하십시오. microsoft.com/en-us/library/ms187373%28SQL.110%29.aspx –

0

통계가 최신입니까? 확인 :

SELECT object_name = Object_Name(ind.object_id) 
,  IndexName = ind.name 
,  StatisticsDate = STATS_DATE(ind.object_id, ind.index_id) 
FROM SYS.INDEXES ind 
order by 
     STATS_DATE(ind.object_id, ind.index_id) desc 

업데이트와 함께 :

exec sp_updatestats; 
+0

OP에서 "실행 직전에 인덱스가 다시 작성되었습니다.": 인덱스 통계는 항상 인덱스 다시 작성 (하지만 열 인덱스 제외)에 의해 업데이트됩니다. 기본적으로 tblFact 인덱스는 덮어 쓰지 않습니다 – gbn

1

당신은 그것을 covering 만들기 위해 tblFact 인덱스에 인클루드로 SomeFact를 추가해야합니다.

현재 테이블이 두 번 액세스됩니다 한 번 인덱스에 대해 한 후 다시 조회 SomeFact를 얻을 수 있도록 중 하나 RID 또는 키 조회 등이 아무튼

'(클러스터 된 인덱스가있을 경우에 따라 다름) 내가 은 암시 적으로 다루는 클러스터 된 인덱스라고 가정하기 때문에 tblDIM에 적용하십시오.

+0

+1 - 그는 여전히 클러스터 된 인덱스 – JNK

+0

에 대한 모든 페이지를 가져와야한다고 확신합니다. 현재 실행 계획과 잘 일치하며, 인덱스는 70 번 액세스됩니다 (희미한 테이블). 주요 조회 (클러스터 된 색인)가 있습니다.사실 열은 검색어에 따라 다르므로 색인을 완전히 덮어 쓰는 것을 주저합니다. – vuht2000

+0

@ vuht2000 : 세 가지 옵션 : 1. 인덱스가없고 모든 쿼리가 1:40을 차지합니다. 2. 클러스터 된 인덱스를 (Mkey, Pkey)로 만듭니다. 3. 현재 인덱스를 덮어 씁니다. 선택 사항 ... – gbn