Bir sorguyu önce bir dizinde, sonra da başka bir dizinde arama yapacak şekilde en iyileştirme


12

Her biri zaman alanları (ortalama julian tarihi için mjd) ve coğrafya pozisyonları (GeoPoint, spacial) ile uydu verilerinden iki set ölçümüm var ve iki set arasındaki tesadüfleri arıyorum, böylece zamanları bir eşikle eşleşiyor 3 saat (veya .125 gün) ve birbirlerinin 200 km'lik mesafeleri.

Hem mjd alanları hem de tablolar ve uzamsal tablolar için dizinler yaptık.

Zaman kısıtlamasına katıldığımda, veritabanı 8 saniyede 100.000 eşleşmeyi hesaplar ve o zamandaki tüm 100.000 eşleşme için mesafeleri hesaplar. Sorgu şöyle görünü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
option( table hint ( h, index(ix_MJD) ), table hint( m, index(ix_MJD) ) )

Ve yürütülen plan:

Yalnızca mjd kısıtlaması

Sıralandığında, mesafelerin 9'u 200 km'nin altındaydı, bu yüzden eşleşmeler var. Sorun, mesafe kısıtlamasını eklediğimde ve bunun yerine çalıştırdığımda,

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) ) )

uzun süre kayboluyor. Açıkçası, 8 saniye içinde, 9'u 200 km'nin altında olan 100.000 zaman eşleşmesi bulabilir, bu nedenle optimize edici alt optimal bir şey deniyor olmalıdır. Plan yukarıdaki mesafelere bir filtre ile yukarıdakine benzer (tahmin ediyorum).

uzamsal sabit ile, uzamsal filtre yok

Bu ile mekansal endeks kullanımını zorlayabilir:

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) ) )

her iki dizinde de her iki kısıtlama

daha sonra 5 maç bulmak için 3 dakika sürer.

Sorgu optimize ediciye ilk olarak MJD indeksi aramasını ve sonra uzamsal indeksi ikinci olarak nasıl kullanacağımı söyleyebilirim (ya da zaten ne yapıyor?) 8 saniyede 200 km'nin altında 9'lu mesafelerle 100.000 eşleşmeyi hesaplayabiliyorsa, uzamsal dizinin eklenmesi daha hızlı olmamasını sağlamamalı mı?

Diğer ipuçları veya fikirler için teşekkürler.

EDIT: Planın ipuçları olmadan nasıl göründüğü sorusuna cevap vermek için, bu (ve sonsuza kadar sürer):

ipucu yok

Ayrıca, bir tabloda neredeyse 1M, diğerinde 8M kayıtlarının bulunduğunu belirtmek gerekir.


Bu ipuçlarını kaldırırsanız sorgu planınız nasıl görünür?
Zane

@Zane, yazıyı düzenledim ve ipucu içermeyen sorgu planı ekledim. Aramaları taramalarla değiştirir ve zamanlama uçsuz bucaksızdır.
user261963

Yanıtlar:


6

Sorun, (ve muhtemelen uzamsal indeksleri bilmek) uzamsal filtrenin zaman filtresinden çok daha seçici olacağını varsayabilir.

Ancak 200km içinde birkaç milyon kaydınız varsa, o zaman çok daha kötü olabilir.

Sizden bazı uzamsal düzen tarafından sıralanan verileri döndüren 200 km'lik kayıtları bulmasını istiyorsunuz. Orada yakın zamanda bulunan kayıtları bulmak, her birinin kontrol edilmesi anlamına gelir.

Ya da kayıtları zamana göre buluyorsunuz ve sonuçları zamana göre alıyorsunuz. Daha sonra, bu listeyi 200 km yarıçapına filtrelemek her birini kontrol etmektir.

Verileri böyle iki aralıkta filtrelerseniz, ikinci filtreyi bir dizin kullanarak uygulamak zorlaşır. Zaman filtresi daha sıkıysa, uzamsal dizini kullanmamasını söylemeniz daha iyi olabilir.

Her ikisi de ayrı ayrı büyükse ve sadece birlikte sıkı olmaları durumunda, daha karmaşık bir sorununuz var, o zaman insanların uzun süredir çözmeye çalıştıkları ve 3D'yi (ve ötesini) kapsayan dizinler tarafından güzel bir şekilde çözülebilecek bir sorun var. Uzay. Bunun dışında SQL Server'da yoktur.

Üzgünüm.

Düzenle: daha fazla bilgi ...

Bu, zaman içindeki belirli bir noktayı kapsayan zaman aralıklarını bulmaya benzer bir sorundur. Bu noktadan önce başlayan kayıtları aradığınızda, bitiş zamanlarının sırasız bir karışıklığı olur - ya da tam tersi. Telefon defterinde soyadları F ile başlayan kişileri ararsanız, ilk adları R ile başlayan kişileri kolayca bulamazsınız. Ve ad üzerindeki bir dizin de aynı nedenden dolayı yardımcı olmuyor. İlk dizininiz bir eşitlik olmadığında, bir sonraki dizinde bir şeyler bulmak zordur.

Şimdi, tarih filtrenizi bir eşitlik filtresine (veya eşitlik filtreleri dizisine) değiştirebiliyorsanız, uzamsal bir dizinin özel bir dizin türü olması ve bileşik bir indeks.

Korkarım, garip bir durumla karşı karşıya kalırsınız. :(

Düzenleme: Deneyin:

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 ile karşılaştırmadan önce 1000'e bölerek kasten kırılganlığı kırdığımı fark ettim. Bu çalışmanın Anahtar Arama'da yapılmasını istiyorum.

Unutmayın, her iki ix_MJD dizininde GeoPoint ve Zaman'ı DAHİL ETMEK için aramalara (ve ipuçlarına) ihtiyaç duyabilirsiniz. Bu kesinlikle sorgu planındaki ısının bir kısmını çıkaracaktır.


Bir şey değiştirip değiştirmediğini bilmiyorum, ama zaman filtresi çok daha seçici.
user261963

Tamam. Peki zaman uyumlu tüm satırları bulmak ve dizin olmadan her yeri kontrol etmek kabul edilebilir mi?
Rob Farley

... o zaman plan orijinal planınıza benziyor, ancak ekstra bir yüklem veya filtreye sahip.
Rob Farley

Hızlı bir düzenleme ile bazı değişiklikler önerdi. M hakkında ipucu vermenize gerek yok, sadece h. Hangisini 1/8 eklediğinizi değiştirebilseniz de, sütunu daha küçük tablodan değiştirdiğinizden ve bu değerleri daha büyük olanı aramak için kullandığınızdan emin olmak, bu da yardımcı olacaktır. H 8M ve m 1M ise, BETWEEN yüklemini bırakın ve sadece h için ipucu verin. Başka bir yolsa, yükleminizi ve ipucunuzu değiştirin (ancak ipucunu değiştirmekten daha iyi, bu sütunları dizininize eklemektir).
Rob Farley

Tüm tablo ipuçlarını çıkarmak, sonunda m arasında yaptığım ve tersi yaptığım sürece, en iyi sonucu verir. Sorgu artık GeoPoint dizinlerini kullanmıyor, ancak bunları yine de verimli bir şekilde kullanmıyordu. MJD dizinine GeoPoint sütununu dahil ettim ve bu çok yardımcı oldu. 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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.