Warum funktioniert dieser speed up my SQL-Abfrage?
Habe ich gelernt, ein trick, eine Weile zurück von einer DBA-Freund, um die Geschwindigkeit bestimmter SQL-Abfragen. Ich erinnere mich, ihn zu erwähnen, dass es etwas damit zu tun hatte, wie SQL Server kompiliert die Abfrage, und dass die Abfrage Weg ist gezwungen, den indizierten Wert.
Hier ist meine ursprüngliche Abfrage (dauert 20 Sekunden):
select Part.Id as PartId, Location.Id as LocationId
FROM Part, PartEvent PartEventOuter, District, Location
WHERE
PartEventOuter.EventType = '600' AND PartEventOuter.AddressId = Location.AddressId
AND Part.DistrictId = District.Id AND Part.PartTypeId = 15
AND District.SubRegionId = 11 AND PartEventOuter.PartId = Part.Id
AND PartEventOuter.EventDateTime <= '4/28/2009 4:30pm'
AND NOT EXISTS (
SELECT PartEventInner.EventDateTime
FROM PartEvent PartEventInner
WHERE PartEventInner.PartId = PartEventOuter.PartId
AND PartEventInner.EventDateTime > PartEventOuter.EventDateTime
AND PartEventInner.EventDateTime <= '4/30/2009 4:00pm')
Hier ist die "optimierte" Abfrage (weniger als 1 Sekunde):
select Part.Id as PartId, Location.Id as LocationId
FROM Part, PartEvent PartEventOuter, District, Location
WHERE
PartEventOuter.EventType = '600' AND PartEventOuter.AddressId = Location.AddressId
AND Part.DistrictId = District.Id AND Part.PartTypeId = 15
AND District.SubRegionId = 11 AND PartEventOuter.PartId = Part.Id
AND PartEventOuter.EventDateTime <= '4/28/2009 4:30pm'
AND NOT EXISTS (
SELECT PartEventInner.EventDateTime
FROM PartEvent PartEventInner
WHERE PartEventInner.PartId = PartEventOuter.PartId
**AND EventType = EventType**
AND PartEventInner.EventDateTime > PartEventOuter.EventDateTime
AND PartEventInner.EventDateTime <= '4/30/2009 4:00pm')
Kann mir jemand im detail erklären, warum läuft so viel schneller? Ich versuche nur, um ein besseres Verständnis dieser.
- Haben Sie versucht, suchen Sie die Abfrage-plan?
- Denn es gibt einen index auf eventtype?
- Haben Sie nicht ein index auf diesem Feld?
- Abhängig von Ihrer Datenbank-engine, ich bin davon ausgegangen, dass Sie SQL 2005/2008
- Ja ich habe es angeschaut, aber es bedeutet nicht nichts zu mir. Die Kosten für die ursprüngliche Serie um 31% auf einen Clustered Index Scan (neben vielen anderen Clustered Index Scans). Die höchsten Kosten in der "optimierten" version ist ein 8% "Clustered Index Scan".
- Beachten Sie, dass, wenn Typ null-Werte zulässt, dann 2 Abfragen sind nicht das gleiche (wie EventType = EventType wäre nicht wahr, wenn Typ NULL IST).
- Eigentlich ist dieses "Feld" ist eine Spalte in einer Ansicht. @hova - ja, das ist SQL Server 2005 Express.
- P. S. Es gibt keine Indizes auf der PartEvent Ansicht-Spalten.
- Ich denke, dass der Punkt über der hinzugefügten Bedingung ohne Null-Werte kann die Erklärung dafür sein. Was ist, wenn Sie ersetzen, dass die Bedingung mit
EventType IS NOT NULL
? - Erfassen Sie eine XML-query für jeden, und diese buchen. Dann können wir spezifische. technet.microsoft.com/en-us/library/ms190646.aspx
- Überprüfung EventType IST NICHT NULL, nicht Beschleunigung der Abfrage.
Du musst angemeldet sein, um einen Kommentar abzugeben.
wahrscheinlich, weil du immer ein Kartesisches Produkt ohne Ihre EventType = EventType
Aus Der WikiPedia: http://en.wikipedia.org/wiki/SQL
"[SQL] macht es zu einfach, zu tun, ein Kartesisches beitreten (Beitritt aller möglichen Kombinationen), die Ergebnisse im "run-away" Ergebnis legt fest, Wann, WO-Klauseln sind falsch. Kartesische joins sind also in der Praxis selten verwendet, dass die Forderung, eine explizite KARTESISCHE keyword gerechtfertigt sein. (SQL-1992 Einführung der CROSS JOIN-Schlüsselwort ermöglicht es dem Benutzer, um klar zu machen, dass ein Kartesisches beitreten soll, sondern die Abkürzung für die "Komma-join" - ohne Prädikat ist noch akzeptabel syntax, die noch lädt den gleichen Fehler.)"
sind Sie eigentlich vor sich geht, durch mehr Zeilen als nötig mit Ihrem ersten Abfrage.
http://www.fluffycat.com/SQL/Cartesian-Joins/
Gibt es eine große Anzahl von Datensätzen mit EventType = Null?
Bevor Sie die zusätzliche Einschränkung Ihrer Unterabfrage hätte Rückgabe alle diese Null-Datensätze, die dann geprüft werden sollen, durch die not Exists-Prädikat für jede Zeile der äußeren Abfrage... So dass die mehr Sie sich einschränken, was die Unterabfrage gibt, der weniger die Zeilen, die gescannt werden sollen, um zu überprüfen, die Nicht Existiert...
Wenn dies der Fall ist, wäre es wahrscheinlich noch schneller, wenn Sie eingeschränkt ist, die Datensätze zu EventType = '600' in der Unterabfrage auch....
SQL Server verwendet einen index lookup, wenn und nur wenn alle Spalten der index in der Abfrage.
Jeden nicht-indizierte Spalte, die Sie hinzufügen, führt einen table scan. Wenn Sie Schränken Sie Ihre Abfrage nach unten früher in Ihrer WHERE-Klausel, die anschließende scans sind schneller. So wird durch das hinzufügen eines Index-scan, wird Ihr Tisch-scans gegen weniger Daten.
Seltsam, hast du ein index definiert mit beiden
EventType
undEventDateTime
es?Edit:
Warten Sie, EventType eine null-Spalte?
Column = Column
bewerten zuFALSE
* wenn es Wert istNULL
. Zumindest mit der Standard-SQL Server-Einstellungen.Sichereres äquivalent wäre
EventType IS NOT NULL
. Sehen Sie, es gibt das gleiche Ergebnis Geschwindigkeit her?*: Meine T-SQL-Referenz sagt, es sollte ausgewertet
TRUE
mitANSI_NULLS
eingestelltOFF
an, aber meine Abfrage Fenster sagt etwas anderes. *confuzzled jetzt*.Jede Entscheidung?
TRUE
,FALSE
,NULL
oderUNKNOWN
? 🙂 Gotta love 'binary' - Logik in SQL 🙁Diese Art der Sache verwendet zu werden, viel häufiger, als es jetzt ist. Oracle 6 für die Instanz verwendet werden, die empfindlich auf die Reihenfolge, in der Sie platziert Einschränkungen in der WHERE-Klauseln. Der Grund, warum Sie Wundern sich wirklich, da haben wir uns so gut erwarten, dass die DB-engine, um immer die besten access-path-egal, wie Sie die Struktur der SQL. Oracle 6 & 7 (ich wechselte zu MSSQL danach) hatte auch das Hinweis-Erweiterung, die Sie verwenden können, sagen Sie der Datenbank, wie Sie es vielleicht gerne zum erstellen der Abfrage-plan.
In diesem speziellen Fall ist es schwierig, eine schlüssige Antwort ohne zu sehen, die eigentliche Suchanfrage, die Pläne aber ich vermute, der Unterschied ist, Sie haben einen zusammengesetzten index, der verwendet EventType, die nicht eingesetzt wird für die erste Abfrage ist aber für die zweite. Dies wäre ungewöhnlich, würde ich erwarten, dass Sie Ihre erste Abfrage, verwendet es trotzdem, so vermute ich, dass die Datenbank-Statistiken veraltet sein könnten, so
REGENERIEREN STATISTIK
dann nochmal versuchen und die Ergebnisse hier posten.