Domanda

Sono stato ispirato dalle buone risposte dal mio su SQL. Ora questo SQL viene eseguito su un DB con Interbase 2009. Si tratta di circa 21 GB di dimensione.

SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
       and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc

Non ci sono 840000 righe con AddrDistance 190000 righe con Indirizzo e 4 con DistanceQueryTask.

La domanda è: si può fare più velocemente? Credo che, la stessa query viene eseguita più volte selezionare bold_id da DistanceQueryTask . Si noti che non sono interessato a stored procedure, basta SQL pianura:)

EDIT1 Ecco il piano di esecuzione corrente:

Statement: SELECT DistanceAsMeters, AddrDistance.Bold_Id, AddrDistance.Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
       and not AddrDistance.bold_id in (select bold_id from DistanceQueryTask)
Order By Created Desc

PLAN (DISTANCEQUERYTASK INDEX (RDB$PRIMARY218))
PLAN SORT (JOIN (JOIN (ADDRDISTANCE NATURAL,ADDRESSFROM INDEX (RDB$PRIMARY234)),ADDRESSTO INDEX (RDB$PRIMARY234)))

E sì, DistanceQueryTask è destinata ad avere un numero basso se righe nel database.

È stato utile?

Soluzione

Uso Registrazione Sinistra e sottointerrogazioni rallenterà qualsiasi richiesta.

È possibile ottenere alcuni miglioramenti con gli indici corretti (su Bold_id, DistanceMeters, PseudoDistanceAsCostKm) ricordate che più indici aumentano la dimensione del database

Altri suggerimenti

Suppongo bold_id è la chiave, e quindi correttamente indicizzato.
Poi la sostituzione della subselect e non ... in da un join potrebbe aiutare l'ottimizzatore.

SELECT DistanceAsMeters, Bold_Id, Created, AddressFrom.CityName_CO as FromCity, AddressTo.CityName_CO as ToCity
FROM AddrDistance
LEFT JOIN Address AddressFrom ON AddrDistance.FromAddress = AddressFrom.Bold_Id
LEFT JOIN Address AddressTo ON AddrDistance.ToAddress = AddressTo.Bold_Id
LEFT JOIN DistanceQueryTask ON AddrDistance.bold_id = DistanceQueryTask.bold_id
Where  DistanceAsMeters = 0 and PseudoDistanceAsCostKm = 0
  and DistanceQueryTask.bold_id is null
Order By Created Desc

Crea un indice per questa parte: (DistanceAsMeters = 0 e PseudoDistanceAsCostKm = 0) perché fa un (cattivo) scansione di tabella per esso: ADDRDISTANCE NATURALE

E cercare di usare il join invece di selezione secondaria come dichiarato da Francois.

Mentre Daniel e Andre sugge un indice aiuta molto.
Suggerirei questo indice (DistanceMeters, PseudoDistanceAsCostKm, Bold_id), in quanto le prime 2 parti di indice è costante, allora la sua una porzione smal dell'indice che è necessario per leggere.

Se è un fatto che FromAddress e / o a indirizzo esistono è possibile modificare il LEFT JOIN a INNER JOIN, perché è spesso più veloce (l'ottimizzatore di query può fare alcune ipotesi).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top