Ho due serie di misurazioni della terra da dati satellitari, ognuna con campi temporali (mjd per data media giuliana) e posizioni geografiche (GeoPoint, spaziale) e sto cercando coincidenze tra le due serie in modo che i loro tempi corrispondano a una soglia di 3 ore (o .125 giorni) e le loro distanze entro 200 km l'una dall'altra.
Ho creato degli indici per entrambi i campi mjd su entrambe le tabelle e le tabelle spaziali.
Quando mi unisco al vincolo temporale, il database calcola 100.000 partite in 8 secondi e calcola le distanze per tutte le 100.000 partite in quel momento. La query è simile alla seguente:
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) ) )
E il piano eseguito è:
Una volta ordinati, 9 delle distanze erano inferiori a 200 km, quindi ci sono partite. Il problema è che quando aggiungo il vincolo di distanza ed eseguo invece questo,
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) ) )
va via per molto tempo. Ovviamente, in 8 secondi, è stato possibile trovare 100.000 fiammiferi, di cui 9 a meno di 200 km, quindi l'ottimizzatore deve provare qualcosa di non ottimale. Il piano è simile al precedente con un filtro sulle distanze (immagino).
Posso forzare l'uso dell'indice spaziale con questo:
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) ) )
che quindi impiega 3 minuti per trovare 5 partite.
Come faccio a dire a Query Optimizer di usare prima l'indice MJD, e poi l'indice spaziale secondo (o è quello che sta già facendo) e c'è un modo per aiutarlo dicendogli quante partite aspettarsi? Se è in grado di calcolare 100.000 partite con distanze in 8 secondi che hanno 9 sotto 200 km, l'aggiunta dell'indice spaziale non dovrebbe renderlo più veloce, non più lento?
Grazie per eventuali altri suggerimenti o idee.
EDIT: per rispondere alla domanda che aspetto ha il piano senza i suggerimenti, questo (e ci vorrà per sempre):
Vale anche la pena ricordare che ci sono quasi 1 milione di record in una tabella e 8 milioni nell'altra