W przypadku pliku, COUNT(DISTINCT)
który ma ~ 1 miliard różnych wartości, otrzymuję plan zapytań z agregatem skrótu, który ma tylko ~ 3 miliony wierszy.
Dlaczego to się dzieje? SQL Server 2012 daje dobre oszacowanie, więc czy jest to błąd w SQL Server 2014, który powinienem zgłosić w Connect?
Zapytanie i słaba ocena
-- 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
Plan zapytań
Pełny skrypt
Oto pełne zgłoszenie sytuacji przy użyciu bazy danych zawierającej tylko statystyki .
Co próbowałem do tej pory
Zagłębiłem się w statystyki dla odpowiedniej kolumny i stwierdziłem, że wektor gęstości pokazuje około 1,1 miliarda różnych wartości. SQL Server 2012 korzysta z tej prognozy i tworzy dobry plan. Zaskakująco wygląda na to, że SQL Server 2014 ignoruje bardzo dokładne oszacowania podane w statystykach, a zamiast tego używa znacznie niższych oszacowań. Powoduje to znacznie wolniejszy plan, który nie rezerwuje prawie wystarczającej ilości pamięci i rozlewa się do tempdb.
Próbowałem flagi śledzenia 4199
, ale to nie naprawiło sytuacji. Na koniec próbowałem zagłębić się w informacje o optymalizatorze za pomocą kombinacji flag śledzenia (3604, 8606, 8607, 8608, 8612)
, jak pokazano w drugiej połowie tego artykułu . Jednak nie byłem w stanie zobaczyć żadnych informacji wyjaśniających złe oszacowanie, dopóki nie pojawiło się w końcowym drzewie wyników.
Problem z połączeniem
Na podstawie odpowiedzi na to pytanie zgłosiłem to również jako problem w Connect