하나의 인덱스를 먼저 찾은 다음 다른 인덱스를 찾도록 쿼리를 최적화하는 방법


12

위성 데이터에서 시간 필드 (평균 julian 날짜의 경우 mjd)와 지리 위치 (GeoPoint, spacial)가있는 두 개의 지구 측정 세트가 있으며 두 세트 간의 시간이 임계 값과 일치하도록 두 세트 사이의 일치를 찾고 있습니다 3 시간 (또는 .125 일) 및 거리 200km 이내

테이블과 공간 테이블 모두에서 mjd 필드에 대한 인덱스를 만들었습니다.

시간 제약 조건에 합류하면 데이터베이스는 8 초 동안 100,000 개의 일치 항목을 계산하고 해당 시간의 100,000 개의 일치 항목에 대한 거리를 계산합니다. 쿼리는 다음과 같습니다.

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

실행 계획은 다음과 같습니다.

mjd 제약 조건 만

정렬하면 거리 중 9 거리가 200km 미만이므로 일치합니다. 문제는 거리 제한을 추가하고 대신 실행하면

select top 10 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
and h.GeoPoint.STDistance(m.GeoPoint)<200000
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

오랫동안 사라집니다. 분명히 8 초 안에 10 만 시간 일치를 발견 할 수 있었으며 그 중 9 개는 200km 미만 이었으므로 최적화 프로그램은 차선책을 시도해야합니다. 계획은 거리에 대한 필터를 사용하여 위와 비슷하게 보입니다 (추측입니다).

공간 제약이 있고 공간 필터가없는

다음과 같이 공간 인덱스를 강제로 사용할 수 있습니다.

select top 5 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0 
from L2V5.dbo.header h join L2.dbo.MLS_Header m 
on h.GeoPoint.STDistance(m.GeoPoint)<200000
and h.mjd between m.mjd-.125 and m.mjd+.125 
option( table hint ( h, index(ix_MJD), index(ix_GeoPoint) ), table hint( m, index(ix_MJD) ) )

두 인덱스가있는 두 제약

그런 다음 5 개의 일치 항목을 찾는 데 3 분이 걸립니다.

쿼리 최적화 프로그램에 먼저 MJD 인덱스 검색을 사용하고 나서 공간 인덱스에 두 번째 (또는 이미 수행중인 작업)를 사용하도록 지시하고 예상 할 일치 항목 수를 알려주는 방법이 있습니까? 200km 미만에서 거리가 9 초인 거리에서 8 초 동안 100,000 개의 일치 항목을 계산할 수 있다면 공간 인덱스를 추가해도 속도가 느려지지 않아야합니까?

다른 팁이나 아이디어를 주셔서 감사합니다.

편집 : 힌트없이 계획이 어떻게 보이는지 질문에 대답하려면 다음과 같이하십시오 (영원히 걸립니다).

힌트가 없습니다

한 테이블에는 거의 1M의 레코드가 있고 다른 테이블에는 8M의 레코드가 있다고 언급 할 가치가 있습니다.


이러한 힌트를 제거하면 쿼리 계획이 어떻게 표시됩니까?
Zane

@ Zane, 게시물을 편집하고 힌트가없는 쿼리 계획을 추가했습니다. 탐색을 스캔으로 대체하고 타이밍이 끔찍합니다.
user261963

답변:


6

문제는 공간 필터가 시간 필터보다 훨씬 더 선택적 일 것이라고 가정 할 수 있다는 것입니다.

그러나 200km 내에 몇 백만 건의 레코드가 있다면 훨씬 더 나빠질 수 있습니다.

200km 내에서 레코드를 찾도록 요청하면 공간 순서로 정렬 된 데이터를 반환합니다. 시간이 가까운 레코드를 찾는 것은 각 레코드를 확인하는 것을 의미합니다.

그렇지 않으면 시간별로 레코드를 찾고 있으며 시간 순서대로 결과를 얻습니다. 그런 다음이 목록을 200km 반경으로 필터링하면 각 목록을 확인해야합니다.

이와 같이 두 범위의 데이터를 필터링하면 인덱스를 사용하여 두 번째 필터를 적용하기가 어렵습니다. 시간 필터가 더 긴 경우 공간 인덱스를 사용하지 말라고 알려주는 것이 좋습니다.

둘 다 개별적으로 크고 단단하게 묶여 있으면 더 복잡한 문제가 있습니다. 사람들이 오랫동안 해결하려고 시도한 문제이며 3D 이상을 포함하는 색인으로 잘 해결할 수 있습니다. 우주. SQL Server에는 해당 서버가 없습니다.

죄송합니다.

편집 : 추가 정보 ...

이것은 특정 시점을 다루는 시간 범위를 찾는 것과 비슷한 문제입니다. 해당 시점 이전에 시작되는 레코드를 검색하면 종료 시간이 정돈되지 않으며 그 반대도 마찬가지입니다. 전화 번호부에서 성이 F로 시작하는 사람을 찾으면 이름이 R로 시작하는 사람을 쉽게 찾을 수 없습니다. 그리고 이름에 대한 색인은 같은 이유로 도움이되지 않습니다. 첫 번째 색인이 같지 않으면 다음 색인에서 물건을 찾기가 어렵습니다.

이제 날짜 필터를 같음 필터 (또는 일련의 같음 필터)로 변경할 수 있다면 공간 인덱스가 특별한 종류의 인덱스이며 두 번째 수준으로 사용할 수 없다는 점을 제외하고는 기회가 될 수 있습니다 복합 인덱스.

그래서 당신은 어색한 상황에 처해 있습니다. :(

편집 : 시도 :

select top 100000 h.Time, m.Time, h.GeoPoint.STDistance(m.GeoPoint)/1000.0
from L2V5.dbo.header h join L2.dbo.MLS_Header m
on h.mjd between m.mjd-.125 and m.mjd+.125
where h.GeoPoint.STDistance(m.GeoPoint)/1000.0 < 200
option( table hint ( h, index(ix_MJD) ) );

200을 비교하기 전에 1000으로 나누어서 의도적으로 Sargability를 깨뜨리고 있습니다.이 작업은 Key Lookup에서 수행하기를 원합니다.

ix_MJD 인덱스 모두에 GeoPoint 및 Time을 포함시켜 조회 (및 힌트)가 필요하지 않도록 할 수 있습니다. 쿼리 계획에서 약간의 열이 발생할 것입니다.


그것이 변경되는지는 모르겠지만 시간 필터는 훨씬 선택적입니다.
user261963

확인. 따라서 모든 시간 일치 행을 찾은 다음 색인없이 각 위치를 확인하는 것이 허용됩니까?
Rob Farley

... 그래서 계획은 원래 계획처럼 보이지만 추가 술어 또는 필터가 있습니다.
Rob Farley

빠른 수정으로 일부 변경 사항을 제안했습니다. 당신은 m에 대해 암시 할 필요가 없습니다. 단지 h입니다. 1/8을 추가하는 것을 바꿀 수 있지만 더 작은 테이블에서 열을 수정하고 그 값을 사용하여 더 큰 테이블을 찾으려면 도움이 될 것입니다. h가 8M이고 m이 1M이면 BETWEEN 술어를 그대로두고 h에 대한 힌트를 제공하십시오. 다른 방법이라면 술어와 힌트를 변경하십시오 (그러나 힌트를 변경하는 것보다 해당 열을 인덱스에 추가하는 것이 좋습니다).
Rob Farley

모든 테이블 힌트를 가져 오는 것은 결국 m 사이에서 다른 방법으로하지 않는 한 가장 잘 작동하는 것 같습니다. 쿼리는 더 이상 GeoPoint 인덱스를 전혀 사용하지 않지만 어쨌든 효율적으로 사용하지 않았습니다. GeoPoint 열을 MJD 색인에 포함 시켰으며 많은 도움이되었습니다. select top 10000 h.Time, m.Time, m.GeoPoint.STDistance(h.GeoPoint), h.mjd-m.mjd from L2V5.dbo.header h join L2.dbo.MLS_Header m on m.GeoPoint.STDistance(h.GeoPoint)<200000 and m.mjd between h.mjd-.125 and h.mjd+.125 order by h.mjd
user261963
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.