Installieren
Ich habe Probleme beim Verstehen einer Kardinalitätsschätzung. Hier ist mein Testaufbau:
- die 2010-Version der Stack Overflow-Datenbank
- SQL Server 2017 CU15 + DDR (KB4505225) - 14.0.3192.2
- das neue CE (Kompatibilitätsstufe 140)
Ich habe diesen proc:
USE StackOverflow2010;
GO
CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
@CommentCount int
AS
BEGIN
SELECT *
FROM dbo.Posts p
WHERE
p.CommentCount = @CommentCount
OPTION (RECOMPILE);
END;
GO
Die dbo.Posts
Tabelle enthält keine nicht gruppierten Indizes oder Statistiken (ein gruppierter Index ist vorhanden Id
).
Wenn Sie nach einem geschätzten Plan für diesen dbo.Posts
Vorgang fragen, werden als "geschätzte Zeilen" 1.934,99 ausgegeben:
EXEC #sp_PostsByCommentCount @CommentCount = 51;
Das folgende Statistikobjekt wurde automatisch erstellt, als ich nach dem geschätzten Plan gefragt habe:
DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);
Die Highlights davon sind:
- Die Statistiken haben eine recht niedrige Abtastrate von 1,81% (67.796 / 3.744.192).
- Es wurden nur 31 Histogrammschritte verwendet
- Der Wert "Alle Dichte" ist
0.03030303
(33 verschiedene Werte wurden abgetastet). - Das letzte
RANGE_HI_KEY
im Histogramm ist 50 mitEQ_ROWS
1
Frage
Wenn Sie einen Wert über 50 (bis einschließlich 2.147.483.647) übergeben, wird die Zeilenschätzung auf 1.934,99 festgelegt. Welche Berechnung oder welcher Wert wird verwendet, um diese Schätzung zu erstellen? Der Legacy-Kardinalitätsschätzer erzeugt übrigens eine Schätzung von 1 Zeile.
Was ich versucht habe
Hier sind einige Theorien, die ich hatte, Dinge, die ich ausprobiert habe, oder zusätzliche Informationen, die ich ausgraben konnte, als ich mich damit befasste.
Dichtevektor
Ich dachte anfangs, es wäre der Dichtevektor, so als hätte ich ihn benutzt OPTION (OPTIMIZE FOR UNKNOWN)
. Der Dichtevektor für dieses Statistikobjekt ist jedoch 3.744.192 * 0.03030303 = 113.460, das ist es also nicht.
Erweiterte Veranstaltungen
Ich habe versucht, eine erweiterte Ereignissitzung durchzuführen, in der das query_optimizer_estimate_cardinality
Ereignis gesammelt wurde (was ich in Paul Whites Blogbeitrag Cardinality Estimation: Combining Density Statistics erfahren habe ), und diese interessanten Leckerbissen erhalten:
<CalculatorList>
<FilterCalculator CalculatorName="CSelCalcColumnInInterval" Selectivity="-1.000"
CalculatorFailed="true" TableName="[p]" ColumnName="CommentCount" />
<FilterCalculator CalculatorName="CSelCalcAscendingKeyFilter" Selectivity="0.001"
TableName="[p]" ColumnName="CommentCount" UseAverageFrequency="true"
StatId="4" />
</CalculatorList>
Es sieht so aus, als wäre der CSelCalcAscendingKeyFilter
Taschenrechner benutzt worden (der andere sagt, er sei fehlgeschlagen, was auch immer das bedeutet). Diese Spalte ist kein Schlüssel oder eindeutig oder unbedingt aufsteigend, aber was auch immer.
Das Googeln dieses Begriffs hat mich zu einigen Blog-Posts geführt:
- Joe Sack - Der CSelCalcAscendingKeyFilter-Rechner ,
- Itzik Ben-Gan - Suchen und Sie scannen Teil II: Aufsteigende Schlüssel
Diese Beiträge geben die neuen CE-Grundlagen für diese Schätzungen außerhalb des Histogramms an, die auf einer Kombination des Dichtevektors und des Änderungszählers der Statistik basieren. Leider habe ich den Dichtevektor bereits ausgeschlossen (glaube ich ?!) und der Änderungszähler ist Null (pro sys.dm_db_stats_properties
).
Fahnen verfolgen
Forrest schlug vor, TF 2363 einzuschalten, um weitere Informationen über den Schätzvorgang zu erhalten. Ich denke, das Relevanteste an dieser Ausgabe ist Folgendes:
Plan for computation:
CSelCalcAscendingKeyFilter(avg. freq., QCOL: [p].CommentCount)
Selectivity: 0.000516798
Dies ist ein Durchbruch (danke, Forrest!): Diese 0.000516798
Zahl (die im Selectivity="0.001"
obigen XE- Attribut unvollständig gerundet zu sein scheint ) multipliziert mit der Anzahl der Zeilen in der Tabelle ist die Schätzung, nach der ich gesucht habe (1.934,99).
Vermutlich fehlt mir etwas Offensichtliches, aber ich konnte nicht rückentwickeln, wie dieser Selektivitätswert im CSelCalcAscendingKeyFilter
Taschenrechner erzeugt wird.