2011-08-04 1 views
4

내 trival 쿼리는 SQL 프로파일 러에 따라 반환하는 데 3 초가 걸리고 많은 양의 읽기가 필요합니다. 왜?SQL Server의 내 공간 인덱스는 여전히 매우 간단한 쿼리에서도 많은 읽기를 필요로합니다. 왜?

모든 지오 코딩 된 지점 인 5,000,000 개의 계정으로 채워진 표가 있습니다. 모든 계좌는 도시의 반경 20 마일 내에 위치하고 있습니다. 내 색인은 그렇게 보입니다.

CREATE SPATIAL INDEX [IX_CI_Geocode] ON [dbo].[CustomerInformation] 
(
    [Geocode] 
)USING GEOGRAPHY_GRID 
WITH (
GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = LOW), 
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

나는 다음과 같은 간단한 쿼리를 실행 :

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326); 
DECLARE @region geography = @g.STBuffer(5000); 

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode)) 
where ci.Geocode.STIntersects(@region) = 1 

그것은 반환 3 초를 소요하고 SQL Server 프로파일에 따라이 12,203의 CPU를 요구하고 1,218,873의 읽습니다. 그것들은 색인을 사용하는 데 엄청난 숫자처럼 보입니다.

왜 이렇게 느린가요? 왜 이렇게 하드 드라이브에서 읽어야합니까? 이 성능을 향상 시키려면 어떻게해야합니까?

쿼리 계획을 보면 아래 스크린 샷의 필터 연산자는 쿼리 비용의 34 %입니다.

enter image description here

는 "클러스터 된 인덱스가 탐색"연산자는 쿼리의 63 %이다.

enter image description here

+0

공간 인덱스에 대한 경험이 없지만 나에게 뛰어 들었던 부분은 추정 행 수와 실제 행 수입니다. 일반적으로 이는 오래된 통계의 표시입니다. 테이블과 인덱스에서 통계를 업데이트 해 보셨습니까? – JNK

+0

좋은 생각 이었지만 전혀 도움이되지 않았습니다. 나는 또 다른 접근법을 사용하여 끝났다. –

답변

1

내 궁극적 인 해결책은 대신 필터를 사용하는 것이 었죠. 그것은 많은 잘못된 오판을 되돌려 주지만 성능 측면에서 3 배 더 빠르다는 것을 알게되었습니다. 결과 세트를 얻은 후에는 거리 함수를 적용하여 신경 쓰지 않는 함수를 제거하고 속도가 빠른 것처럼 보입니다.

첫 번째 선택 쿼리는 500 만 개의 계정에서 1 초가 걸립니다. 두 번째는 3 초가 걸립니다.

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326); 
DECLARE @region geography = @g.STBuffer(5000); 

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode)) 
where ci.Geocode.Filter(@region) = 1 


select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode)) 
where ci.Geocode.STIntersects(@region) = 1 
0

내 수학 능력에 기반하여 STBuffer()를 처음 사용하는 경우에는 실제로 관심이 없다면 추가 작업이 필요합니다.

나에게 다음을 시도해보고 결과를 알려주시겠습니까?

DECLARE @g geography = geography::Point(41.848039, -87.96361, 4326); 

select count(0) from CustomerInformation ci WITH(INDEX(IX_CI_Geocode)) 
where ci.Geocode.STDistance(@g) <= 5000 

반면에 데이터베이스를 제공 할 수있는 방법이 있습니까? 그래서 직접 테스트 할 수 있습니까?