2017-03-07 3 views
-2

Ich habe eine Tabelle (nennen wir es A) in SQL Server 2016, die ich abfragen möchte. Ich muss nur die Zeilen auswählen, die einen definitiven Status haben, daher muss ich einige Zeilen ausschließen. Es gibt eine weitere Tabelle (B), die die Datensatz-ID aus der Tabelle A und zwei Spalten, Spalte1 und Spalte2, enthält. Wenn diese Spalten nicht leer sind, kann der entsprechende Datensatz als endgültig betrachtet werden. Zwischen den Tabellen A und B besteht eine Eins-zu-eins-Beziehung. Da diese Tabellen ziemlich groß sind, möchte ich die effizienteste Abfrage verwenden. Welches sollte ich wählen?Welcher ist der schnellste Weg, um diese SQL-Abfrage auszuführen?

SELECT * 
FROM TableA 
WHERE record_id IN 
    (SELECT record_id FROM TableB WHERE col1 IS NOT NULL AND col2 IS NOT NULL) 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b ON a.record_id = b.record_id 
WHERE b.col1 IS NOT NULL AND b.col2 IS NOT NULL 

SELECT a.* 
FROM TableA a 
INNER JOIN TableB b 
ON a.record_id = b.record_id 
    AND b.col1 IS NOT NULL 
    AND b.col2 IS NOT NULL 

Natürlich, wenn es einen noch schnelleren Weg gibt, an den ich nicht gedacht hätte, bitte teilen. Ich wäre auch sehr neugierig zu wissen, warum eine Abfrage schneller ist als die anderen.

+2

Bitte lesen Sie Eric Lipperts exzellentes [Which is faster?] (Https://ericlippert.com/2012/12/17/performance-rant/): "... Wenn Sie zwei Pferde haben und wissen möchten, welche Von den beiden ist das schneller, als deine Pferde zu rasen. Schreibe keine kurzen Beschreibungen der Pferde, poste sie im Internet und frage zufällige Fremde, was schneller ist ... " –

+2

Warum versuchst du es nicht und findest es aus? –

+0

tat ich, aber die Ergebnisse variieren. Die Unterschiede sind ziemlich signifikant (~ 20%), aber die schnellere Abfrage ist nicht immer die gleiche ... –

Antwort

0
WITH cte AS 
(SELECT b.record_id, b.col1, b.col2 
FROM TableB b 
WHERE col1 IS NULL 
AND col2 IS NULL --if the field isn't NULL, it might be quicker to do <> '') 

SELECT a.record_id, a.identifyColumnsNeededExplicitely 
FROM cte 
JOIN TableA a ON a.record_id = cte.record_id 
ORDER BY a.record_id 
+0

Warum genau würde ein CTE die Leistung hier verbessern? –

+0

Eigentlich möchten Sie möglicherweise diese Abfrage FROM tableA anstelle von FROM cte tun. Das sollte es schneller machen; Ein CTE ermöglicht es, dass die Tabelle (bereits gefiltert) in mem gespeichert wird (was am wichtigsten ist, nur einmal gelesen zu werden), wodurch die Abfrage schneller wird. Im nächsten Schritt, verwenden Sie den Ausführungsplan, indexieren Sie die Tabelle, die ineffizient ist, neu. – WickedFan

0

In der Praxis des Ausführungsplan wird tun, was es mag, je nach Ihrer aktuellen Indizes/gruppierten Index/Fremdschlüssel/Einschränkungen/table stastics (aka Anzahl der Zeilen/allgemeine containt Ihrer Zeilen/...). Jede Analyse sollte von Fall zu Fall durchgeführt werden und was für 2 Tabellen gilt, kann nicht für 2 andere Tabellen gelten.

theorically,

Ohne Index sollte das erste man das Beste sein, da es eine Optimierung auf den Betrieb mit 1 Tisch Scan TableB machen, 2 Inhalte auch scannen auf TableB und 1 Tisch scannen auf Tabelle1.

Mit einem Fremdschlüssel auf TableA.record_id, der auf TableB.record_id verweist ODER ein Index in beiden Spalten, sollte der zweite schneller sein, da er einen Scanindex und 2 konstanten Scan erstellt.

In seltenen Fällen könnte es die dritte sein, abhängig von TableB stats. Aber nicht weit von Nummer 2, da Nummer 3 den gesamten TableB scannt.

In noch seltener Fall weder der 3.

Was ich tryng ist zu sagen: „Da wir nicht haben weder Tabellen noch Zeilen, öffnen Sie SQL Management, setzen Sie die Statistiken ON und Versuch es selber."

Verwandte Themen