it-swarm.com.de

SQL-Beziehung zwischen Teilbaumkosten und Leistungszeit

Welche allgemeine Beziehung besteht zwischen "SQL Final Subtree-Kosten" und "Abfragezeitleistung"?

Beispiel: Wenn eine Abfrage optimiert wird und die Kosten für den Teilbaum zwischen 0,2 und 0,1 liegen, bedeutet dies, dass die Abfragezeit doppelt so schnell ist? Ich sehe dies nicht in meinen Abfragen.

Wir haben einen Server und können die Abfrageleistung selbst mit "Statistikzeit einstellen auf" und "DBCC DROPCLEANBUFFERS" nicht wirklich messen. Auf dem Server laufen verschiedene Prozesse ab, Transaktionen, Programme und Hintergrundelemente.

Vielen Dank,

6
user129291

Die Teilbaumkosten entsprechen den geschätzten Kosten eines Plans. Dies kann hilfreich sein, wenn Sie untersuchen, warum das Abfrageoptimierungsprogramm einen Plan einem anderen vorgezogen hat. Beispielsweise könnten Sie einen Plan mit einem Hash-Join sehen und denken, dass ein Loop-Join eine effizientere Wahl gewesen wäre. Das Hinzufügen eines Abfragehinweises zum Erzwingen eines Loop-Joins und das Vergleichen der Teilbaumkosten kann hilfreich sein, um festzustellen, warum SQL Server einen Hash-Join ausgewählt hat.

Die geschätzten Kosten des Plans stimmen aus vielen Gründen häufig nicht mit der "Leistungszeit" einer Abfrage überein, einschließlich Hardwareunterschieden, Blockierung durch andere Prozesse, Gesamtauslastung des Servers, Modellbeschränkungen und Annahmen, die auf unvollständigen Informationen basieren. Darüber hinaus sind Teilbaumkosten von 0,1 gegenüber 0,2 überhaupt kein bedeutender Unterschied. Wenn Sie eine Abfrage haben, deren relative Kosten für den Rest Ihrer Arbeitslast gering sind, die jedoch lange ausgeführt wird, ist dies ein Hinweis darauf, dass das Abfrageoptimierungsprogramm eine falsche Annahme oder Ableitung vornimmt. Die Hauptursache für diese Art von Problemen sind häufig Kardinalitätsschätzungen. Andererseits wird manchmal eine relativ teure Abfrage für eine lange Zeit ausgeführt. Ein Blick auf die Teile des Plans, die voraussichtlich lange dauern, kann nützliche Hinweise darauf geben, warum die Abfrage lange ausgeführt wird. Einige Abfragetuner weisen Sie jedoch an, die geschätzten Kosten überhaupt nicht zu berücksichtigen.

Im Folgenden finden Sie einige Beispielabfragen, um zu zeigen, dass zwischen den geschätzten Kosten und der Laufzeit ein extremer Unterschied bestehen kann. Ich teste auf SQL Server 2017, aber es ist möglich, in allen Versionen ähnliche Demos zu erstellen. Zuerst habe ich 100.000 aufeinanderfolgende Ganzzahlen in einen Haufen gelegt:

CREATE TABLE dbo.OptimizerUnits (ID BIGINT NOT NULL);

INSERT INTO dbo.OptimizerUnits WITH (TABLOCK)
SELECT TOP (100000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);

Betrachten Sie die folgende Abfrage:

SELECT ID
FROM dbo.OptimizerUnits 
WHERE 
(ID % 10) % 101  = 10

Ein Mensch kann sich diese Abfrage ansehen und daraus schließen, dass keine Zeilen zurückgegeben werden, aber im Optimierer ist diese Art von Logik derzeit nicht integriert. Stattdessen wird davon ausgegangen, dass ungefähr 990 Zeilen zurückgegeben werden. Dies ergibt für die folgende Abfrage geschätzte Gesamtkosten von 79590,1 Einheiten:

WITH OptimizerUnitsCTE (ID) AS 
(
    SELECT ID
    FROM dbo.OptimizerUnits 
    WHERE 
    (ID % 10) % 101  = 10
)
SELECT TOP (100) t1.ID, t2.ID, t3.ID
FROM OptimizerUnitsCTE t1
CROSS JOIN OptimizerUnitsCTE t2
CROSS JOIN OptimizerUnitsCTE t3
ORDER BY t1.ID + t2.ID + t3.ID DESC;

Die Abfrage wird jedoch auf meinem Computer in weniger als 50 ms ausgeführt.

Gehen wir jetzt in die andere Richtung. Betrachten Sie die folgende Abfrage:

SELECT ID
FROM dbo.OptimizerUnits 
WHERE 
(ID % 10) % 101  = 1
AND (ID % 10) % 102  = 1
AND (ID % 10) % 103  = 1
AND (ID % 10) % 104  = 1

Wieder einmal könnte ein Mensch ableiten, dass die obige Abfrage genau 10000 Zeilen zurückgibt. Das Abfrageoptimierungsprogramm weiß das nicht und vermutet, dass die Abfrage nur 16.7439 Zeilen zurückgibt. Dies führt zu geschätzten Kosten von 1,45306 Optimierungseinheiten für die folgende Abfrage:

WITH OptimizerUnitsCTE (ID) AS 
(
    SELECT ID
    FROM dbo.OptimizerUnits 
    WHERE 
    (ID % 10) % 101  = 1
    AND (ID % 10) % 102  = 1
    AND (ID % 10) % 103  = 1
    AND (ID % 10) % 104  = 1
)
SELECT TOP (100) t1.ID, t2.ID, t3.ID
FROM OptimizerUnitsCTE t1
CROSS JOIN OptimizerUnitsCTE t2
CROSS JOIN OptimizerUnitsCTE t3
ORDER BY t1.ID + t2.ID + t3.ID DESC;

Ich habe die Abfrage eine Weile auf meinem Computer ausgeführt und schätze, dass der Abschluss ungefähr 4,5 Tage dauern würde.

Zusammenfassend lässt sich sagen, dass bei Schätzungen mit schlechter Kardinalität eine Abfrage mit Kosten von 79590,1 Einheiten weniger als eine Sekunde und eine Abfrage mit Kosten von 1,45306 Einheiten etwa 4,5 Tage dauert.

9
Joe Obbish