SQL Server 2014 COUNT (DISTINCT x) ignoriert den Statistikdichtevektor für Spalte x


15

Für einen COUNT(DISTINCT)mit ~ 1 Milliarde verschiedenen Werten erhalte ich einen Abfrageplan mit einem Hash-Aggregat, das auf nur ~ 3 Millionen Zeilen geschätzt wird.

Warum passiert dies? SQL Server 2012 liefert eine gute Schätzung. Ist dies ein Fehler in SQL Server 2014, den ich bei Connect melden sollte?

Die Abfrage und schlechte Schätzung

-- Actual rows: 1,011,719,166
-- SQL 2012 estimated rows: 1,079,130,000 (106% of actual)
-- SQL 2014 estimated rows: 2,980,240 (0.29% of actual)
SELECT COUNT(DISTINCT factCol5)
FROM BigFactTable
OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE

-- Stats for the factCol5 column show that there are ~1 billion distinct values
-- This is a good estimate, and it appears to be what the SQL 2012 CE uses
DBCC SHOW_STATISTICS (BigFactTable, _WA_Sys_00000005_24927208)
--All density   Average Length  Columns
--9.266754E-10  8               factCol5
SELECT 1 / 9.266754E-10
-- 1079126520.46229

Der Abfrageplan

Bildbeschreibung hier eingeben

Vollständiges Skript

Hier finden Sie eine vollständige Darstellung der Situation mit einer Datenbank, die nur Statistiken enthält .

Was ich bisher versucht habe

Ich habe die Statistiken für die relevante Spalte durchgesehen und festgestellt, dass der Dichtevektor geschätzte ~ 1,1 Milliarden verschiedene Werte anzeigt. SQL Server 2012 verwendet diese Schätzung und erstellt einen guten Plan. Überraschenderweise scheint SQL Server 2014 die sehr genaue Schätzung der Statistik zu ignorieren und verwendet stattdessen eine viel niedrigere Schätzung. Dies führt zu einem viel langsameren Plan, der nicht genügend Arbeitsspeicher reserviert und nicht in Tempdb abläuft.

Ich habe trace flag ausprobiert 4199, aber das hat die Situation nicht verbessert. Zuletzt habe ich versucht, Informationen zum Optimierer über eine Kombination von Ablaufverfolgungsflags abzurufen (3604, 8606, 8607, 8608, 8612), wie in der zweiten Hälfte dieses Artikels gezeigt . Ich konnte jedoch keine Informationen sehen, die die schlechte Schätzung erklären, bis sie im endgültigen Ausgabebaum erschien.

Verbindungsproblem

Aufgrund der Antworten auf diese Frage habe ich dies auch als Problem in Connect abgelegt

Antworten:


14

Die Art und Weise, wie die Kardinalitätsschätzung abgeleitet wird, scheint mir sicherlich nicht intuitiv zu sein. Die Berechnung der eindeutigen Anzahl (sichtbar mit Extended Events oder Trace-Flags 2363 und 3604) lautet:

Statistikableitung

Beachten Sie die Kappe. Die allgemeine Logik hierfür scheint sehr vernünftig zu sein (es kann keine eindeutigeren Werte geben), die Obergrenze wird jedoch anhand von Stichprobenstatistiken mit mehreren Spalten angewendet :

DBCC SHOW_STATISTICS 
    (BigFactTable, [PK_BigFactTable])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

PK Stats

Dies zeigt 2.980.235 Zeilen, die aus 3.439.431.721 mit einem Dichtevektor auf dem Col5-Niveau von 3,35544E-07 abgetastet wurden. Der Kehrwert davon ergibt eine Anzahl eindeutiger Werte von 2.980.235, die unter Verwendung realer Mathematik auf 2.980.240 gerundet werden.

Nun stellt sich bei Stichprobenstatistiken die Frage, welche Annahmen das Modell über die Anzahl der unterschiedlichen Werte treffen sollte. Ich würde erwarten, dass es extrapoliert, aber das wird nicht gemacht, und vielleicht absichtlich.

Intuitiver würde ich erwarten, dass anstelle der mehrspaltigen Statistik die Dichte von Col5 betrachtet wird (aber nicht):

DBCC SHOW_STATISTICS 
    (BigFactTable, [_WA_Sys_00000005_24927208])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

Col5-Statistiken

Hier beträgt die Dichte 9,266754E-10, deren Kehrwert 1,079,126,528 beträgt .

Eine naheliegende Problemumgehung besteht in der Zwischenzeit darin, die mehrspaltigen Statistiken mit einem vollständigen Scan zu aktualisieren. Das andere ist, den ursprünglichen Kardinalitätsschätzer zu verwenden.

Das von Ihnen geöffnete Connect-Element, mit SQL 2014 abgetastete mehrspaltige Statistiken, überschreiben genauere einspaltige Statistiken für nicht führende Spalten . Es ist für SQL Server 2017 als " Fest" markiert .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.