Frage

wurde ich von den guten Antworten inspiriert von meinem früheren Frage über SQL. Nun ist diese SQL auf einem DB läuft mit Interbase 2009. Es ist ca. 21 GB groß.

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

Es gibt 840.000 Zeilen mit AddrDistance 190000 Reihen mit Adresse und 4 mit DistanceQueryTask.

Die Frage ist, kann dies schneller geschehen? Ich denke, ist die gleiche Abfrage oft wählen bold_id von DistanceQueryTask laufen. Beachten Sie, dass ich in Stored Procedures bin nicht daran interessiert, einfach nur SQL:)

EDIT1 Hier ist der aktuelle Ausführungsplan:

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

Und ja, DistanceQueryTask soll eine geringe Anzahl, wenn Zeilen in der Datenbank haben.

War es hilfreich?

Lösung

Mit LEFT JOIN und Unterabfragen werden jede Abfrage verlangsamen.

Sie kann einige Verbesserungen mit der richtigen Indizes erhalten (auf Bold_id, Distanzmessgeräte, PseudoDistanceAsCostKm) daran erinnern, dass mehrere Indizes die Größe der Datenbank

erhöhen

Andere Tipps

Ich nehme an bold_id ist Ihr Schlüssel und damit korrekt indiziert.
Dann ersetzt die subselect und nicht ... in durch ein join könnte das Optimierungsprogramm helfen.

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

Erstellen Sie einen Index für diesen Teil: (DistanceAsMeters = 0 und PseudoDistanceAsCostKm = 0) denn es macht eine (sehr schlecht) Table-Scan für sie: ADDRDISTANCE NATURAL

Und versuchen die Verknüpfung statt Subselect zu verwenden, wie von Francois angegeben.

Als Daniel und Andre sugges ein Index hilft viel.
Ich würde vorschlagen, diesen Index (Distanzmessgeräte, PseudoDistanceAsCostKm, Bold_id), weil die ersten zwei Teile des Index konstant ist, dann ist es ein Smal Teil des Index, der zum Lesen benötigt wird.

Wenn es eine Tatsache ist, dass Absenderadresse und / oder toaddress existieren Sie die LEFT JOIN INNER JOIN ändern können, weil es oft schneller ist (der Abfrageoptimierer einige Annahmen getroffen werden können).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top