Wenn ich dies tue, dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)
erhalte ich das folgende Ergebnis für die Berichts-ID 18698:
Für diese Abfrage:
SELECT *
FROM Reports_Documents
WHERE ReportID = 18698 option (recompile)
Ich bekomme einen Abfrageplan, der ein Clustered Index Seek auf macht , PK_Reports_Documents
wie erwartet.
Was mich jedoch verwirrt, ist der falsche Wert für die geschätzte Anzahl der Zeilen:
Nach dieser :
Wenn der Wert der WHERE-Klausel der Beispielabfrage einem Histogramm-RANGE_HI_KEY-Wert entspricht, verwendet SQL Server die Spalte EQ_ROWS im Histogramm, um die Anzahl der Zeilen zu bestimmen, die gleich sind
Dies ist auch so, wie ich es erwarten würde, aber es scheint im wirklichen Leben nicht der Fall zu sein. Ich habe auch einige andere RANGE_HI_KEY
Werte ausprobiert , die in dem von bereitgestellten Histogramm vorhanden waren, show_statistics
und habe dasselbe erlebt. In meinem Fall scheint dieses Problem dazu zu führen, dass einige Abfragen sehr unoptimale Ausführungspläne verwenden, was zu einer Ausführungszeit von einigen Minuten führt, während ich es mit einem Abfragehinweis in 1 Sekunde ausführen kann.
Alles in allem: Kann mir jemand erklären, warum EQ_ROWS
das Histogramm nicht für die geschätzte Anzahl der Zeilen verwendet wird und woher die falsche Schätzung stammt?
Ein bisschen mehr (möglicherweise hilfreiche) Informationen:
- Die automatische Erstellung von Statistiken ist aktiviert und alle Statistiken sind auf dem neuesten Stand.
- Die abgefragte Tabelle enthält ungefähr 80 Millionen Zeilen.
PK_Reports_Documents
ist eine Kombinations-PK bestehend ausReportID INT
undDocumentID CHAR(8)
Die Abfrage scheint insgesamt 5 verschiedene Statistikobjekte zu laden, die alle ReportID
+ einige andere Spalten aus der Tabelle enthalten. Sie wurden alle frisch aktualisiert. RANGE_HI_KEY
In der folgenden Tabelle ist der höchste Wert der oberen Spalte im Histogramm angegeben.
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| name | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents | 1 | 0 | 0 | Stationary | 18722 | 0 | 2228,526 | 0 | 1 |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 | 62 | 0 | 0 | Stationary | 18698 | 0 | 2228,526 | 0 | 1 |
| _dta_stat_1629248859_1_1_59 | 76 | 0 | 1 | Stationary | 18686 | 50,56393 | 1 | 0 | 13397,04 |
| _dta_stat_1629248859_1_22_14_18_12_6 | 95 | 0 | 1 | Stationary | 18698 | 0 | 2228,526 | 0 | 1 |
| _dta_stat_1629248859_1_7_14_4_23_62 | 96 | 0 | 1 | Stationary | 18698 | 56,63327 | 21641,5 | 0 | 14526,44 |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
sp_updatestats
wird voraussichtlich jede Nacht ausgeführt, um die Statistiken zu aktualisieren.
_dta_
Statistiken jedoch nicht erstellt , sie waren da, seit ich meinen ersten Blick auf die DB geworfen habe. Ich wusste nicht, dass die Verwendung der Empfehlungen solche nachteiligen Auswirkungen haben kann ...