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


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.