Ich habe zwei Sätze von Erdmessungen aus Satellitendaten, jeweils mit Zeitfeldern (mjd für Mean Julian Date) und geografischen Positionen (GeoPoint, Spacial), und ich suche nach Übereinstimmungen zwischen den beiden Sätzen, so dass ihre Zeiten mit einem Schwellenwert von übereinstimmen 3 Stunden (oder .125 Tage) und deren Entfernungen bis zu 200 km voneinander entfernt.
Ich habe sowohl für Tabellen als auch für räumliche Tabellen Indizes für die mjd-Felder erstellt.
Wenn ich mich nur der Zeitbeschränkung anschließe, berechnet die Datenbank 100.000 Übereinstimmungen in 8 Sekunden und berechnet die Entfernungen für alle 100.000 Übereinstimmungen in dieser Zeit. Die Abfrage sieht folgendermaßen aus:
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) ) )
Und der ausgeführte Plan ist:
Bei Sortierung lagen 9 der Entfernungen unter 200 km, es gibt also Übereinstimmungen. Das Problem ist, wenn ich die Abstandsbeschränkung hinzufüge und diese stattdessen ausführe,
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) ) )
es geht für eine lange Zeit weg. Offensichtlich konnte es in 8 Sekunden 100.000 Zeitmatches finden, von denen 9 unter 200 km lagen. Der Optimierer muss also etwas suboptimales ausprobieren. Der Plan sieht ähnlich aus wie oben mit einem Filter für die Entfernungen (ich vermute).
Damit kann ich die Verwendung des räumlichen Index erzwingen:
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) ) )
Das dauert dann 3 Minuten, um 5 Übereinstimmungen zu finden.
Wie kann ich das Abfrageoptimierungsprogramm anweisen, zuerst die MJD-Indexsuche und dann die räumliche Indexsuche zu verwenden (oder ist es das, was es bereits tut)? Wenn es 100.000 Übereinstimmungen mit Entfernungen in 8 Sekunden mit 9 unter 200 km berechnen kann, sollte die Addition des räumlichen Index es nicht schneller und nicht langsamer machen?
Vielen Dank für weitere Tipps oder Ideen.
EDIT: Um die Frage zu beantworten, wie der Plan ohne die Hinweise aussieht, ist dies (und es dauert ewig):
Es ist vielleicht auch erwähnenswert, dass die eine Tabelle fast 1 Million Datensätze und die andere 8 Millionen Datensätze enthält
quelle
Antworten:
Das Problem ist, dass es davon ausgehen könnte (und wenn man räumliche Indizes kennt, wird dies wahrscheinlich der Fall sein), dass der räumliche Filter viel selektiver ist als der Zeitfilter.
Aber wenn Sie ein paar Millionen Datensätze innerhalb von 200 km haben, könnte es bedeutend schlimmer sein.
Sie fordern ihn auf, Datensätze innerhalb von 200 km zu finden, die Daten in räumlicher Reihenfolge zurückgeben. Wenn Sie die zeitnahen Datensätze dort finden, müssen Sie jeden einzelnen überprüfen.
Oder Sie finden Datensätze nach Zeit und erhalten Ergebnisse in zeitlicher Reihenfolge. Das Filtern dieser Liste auf den Radius von 200 km ist eine Frage der Überprüfung.
Wenn Sie die Daten in zwei Bereichen filtern, wird es schwierig, den zweiten Filter mithilfe eines Index anzuwenden. Es empfiehlt sich möglicherweise, den räumlichen Index nicht zu verwenden, wenn der Zeitfilter enger ist.
Wenn beide einzeln groß sind und sie nur zusammen eng sind, haben Sie ein komplexeres Problem, das die Leute seit langem zu lösen versucht haben und das durch Indizes, die 3D (und darüber hinaus) abdecken, gut gelöst werden kann. Raum. Nur dass SQL Server sie nicht hat.
Es tut uns leid.
Bearbeiten: mehr Infos ...
Dies ist ein ähnliches Problem wie das Auffinden von Zeitbereichen, die einen bestimmten Zeitpunkt abdecken. Wenn Sie nach Datensätzen suchen, die vor diesem Zeitpunkt beginnen, gibt es ein ungeordnetes Durcheinander der Endzeiten - und umgekehrt. Wenn Sie im Telefonbuch nach Personen suchen, deren Nachnamen mit F beginnen, können Sie nicht hoffen, die Personen zu finden, deren Vornamen sehr leicht mit R beginnen. Und auch ein Index zum Vornamen hilft aus dem gleichen Grund nicht. Das Finden von Dingen in diesem nächsten Index ist schwierig, wenn Ihr erster Index keine Gleichheit ist.
Wenn Sie nun Ihren Datumsfilter in einen Gleichheitsfilter (oder eine Reihe von Gleichheitsfiltern) ändern könnten, hätten Sie eine Chance, mit der Ausnahme, dass ein räumlicher Index eine spezielle Art von Index ist und nicht als zweite Ebene in verwendet werden kann ein zusammengesetzter Index.
Ich fürchte, Sie haben eine unangenehme Situation. :(
Bearbeiten: Versuchen:
Beachten Sie, dass ich vor dem Vergleich mit 200 absichtlich die Sargabilität durch Division durch 1000 unterbreche. Ich möchte, dass diese Arbeit in der Schlüsselsuche ausgeführt wird.
Wohlgemerkt, Sie könnten die Notwendigkeit von Nachschlägen (und Hinweisen) vermeiden, indem Sie GeoPoint und Time in beiden ix_MJD-Indizes einschließen. Das wird dem Abfrageplan sicherlich etwas Wärme entziehen.
quelle
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