2017-03-23 2 views
1

항목 위치를 저장하는 2012 SQL 데이터베이스의 지형 필드에 공간 인덱스가 설정되었습니다. 약 15,000 개의 아이템이 있습니다.범주 필드를 포함한 SQL 공간 인덱싱

주어진 위도/경도에서 N 킬로미터의 반경 내에있는 총 아이템을 반품해야합니다.

나는 이것을 할 수 있으며 빠릅니다.

DECLARE @radius GEOGRAPHY = GEOGRAPHY::Point(@Lat, @Lng, 4326).STBuffer(@RadiusInMetres*1000) 

SELECT 
COUNT(*) AS Total 
FROM dbo.Items i 
WHERE 
i.LatLngGeo.STIntersects(@radius) = 1 

그러나 지금해야 할 일은 주어진 카테고리 및 가격과 일치하는 항목을 얻기 위해 여러 필드로 필터링하는 것입니다.

DECLARE @radius GEOGRAPHY = GEOGRAPHY::Point(@Lat, @Lng, 4326).STBuffer(@RadiusInMetres*1000) 

SELECT 
COUNT(*) AS Total 
FROM dbo.Items i 
WHERE 
i.LatLngGeo.STIntersects(@radius) = 1 AND 
(i.Category = @Category OR @Category is null) AND 
(i.Price < @Price OR @Price is null) 

이 약 10 + 초 동안 멀리 갈기, 나는 공간 인덱스에 VARCHAR 또는 번호 필드를 추가하는 방법을 찾을 수 있습니다.

속도를 높이려면 어떻게해야합니까?

+0

쿼리 계획은 어떻게 생겼습니까? 공간 인덱스를 사용하고 있습니까? –

답변

0

I는 다음과 같이 시작합니다 :

--Query 1 - use a CTE to split the two filters 
DECLARE @radius GEOGRAPHY = GEOGRAPHY::Point(@Lat, @Lng, 4326).STBuffer(@RadiusInMetres * 1000); 

WITH InRadius AS (
    SELECT * FROM dbo.Items WHERE LatLngGeo.STIntersects(@radius) = 1) 
SELECT 
    COUNT(*) 
FROM 
    InRadius 
WHERE 
    ISNULL(@Category, Category) = Category 
    AND ISNULL(@Price, Price) = Price; 
GO 
--Query 2 - use a temp table to *definitely(split the two filters 
DECLARE @radius GEOGRAPHY = GEOGRAPHY::Point(@Lat, @Lng, 4326).STBuffer(@RadiusInMetres * 1000); 

IF OBJECT_ID('tempdb..#temp') IS NOT NULL 
    DROP TABLE #temp; 
WITH InRadius AS (
    SELECT * FROM dbo.Items WHERE LatLngGeo.STIntersects(@radius) = 1) 
SELECT * INTO #temp FROM InRadius; 
SELECT 
    COUNT(*) 
FROM 
    #temp 
WHERE 
    ISNULL(@Category, Category) = Category 
    AND ISNULL(@Price, Price) = Price; 

실행하는 쿼리를 몇 번, 원래 스크립트에 비해 다음 벤치 마크를.

또 다른 트릭은 원본 쿼리를 복사 한 다음 실행 계획을 보는 것입니다. 찾고자하는 것은 쿼리 당 분할 비율로, 이상적으로는 98 % : 1 % : 1 %와 같을 것입니다. 즉 원래 쿼리는 작업의 98 %를 차지하지만 실제로는 매우 다르게 보일 것입니다.

이 방법이 도움이되지 않고 임시 테이블을 사용할 수 있다면 필터링 대상 기준과 일치하는 임시 테이블에 인덱스를 추가하십시오. 그러나 단지 15,00 개의 행을 사용하면 인덱스 효과가 거의 감지 할 수 없게됩니다.

마지막으로 임시 테이블에로드되는 데이터를 에만 필터링 할 항목으로 제한 할 수 있습니다. 결국 원하는 것만 큼 끝까지 계산할 수 있습니다.

것은 그냥 빨리 정리해 보자 (이미 빠른 말한다) 당신의 공간 쿼리와 일치하는 데이터

  • 추출물;
  • GEOGRAPHY를 결과에서 제외하고 임시 테이블에 저장합니다.
  • 인덱스 모든 필터의 속도를 높이기위한 임시 테이블.
  • 이제 COUNT (*)는 데이터의 하위 집합 (공간 데이터 없음)에 있어야하며 최적화 프로그램은 근접 필터와 결합 할 수 없습니다.
  • 이익!