Для a, COUNT(DISTINCT)
который имеет ~ 1 миллиард различных значений, я получаю план запроса с агрегатом хешей, который оценивается в ~ 3 миллиона строк.
Почему это происходит? SQL Server 2012 дает хорошую оценку, так что это ошибка в SQL Server 2014, о которой я должен сообщить в Connect?
Запрос и плохая оценка
-- 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
План запроса
Полный сценарий
Вот полное воспроизведение ситуации с использованием базы данных только для статистики .
Что я пробовал до сих пор
Я копался в статистике для соответствующего столбца и обнаружил, что вектор плотности показывает приблизительно 1,1 миллиарда различных значений. SQL Server 2012 использует эту оценку и вырабатывает хороший план. Удивительно, но SQL Server 2014 игнорирует очень точную оценку, предоставленную статистикой, и вместо этого использует гораздо более низкую оценку. Это приводит к гораздо более медленному плану, который не резервирует почти достаточно памяти и разливает для tempdb.
Я попробовал трассировать флаг 4199
, но это не исправило ситуацию. Наконец, я попытался найти информацию оптимизатора с помощью комбинации флагов трассировки (3604, 8606, 8607, 8608, 8612)
, как показано во второй половине этой статьи . Однако я не смог увидеть какую-либо информацию, объясняющую неверную оценку, пока она не появилась в конечном итоговом дереве.
Проблема с подключением
Основываясь на ответах на этот вопрос, я также подал это как проблему в Connect