статистика актуальна, но оценка неверна

12

Когда я dbcc show_statistics ('Reports_Documents', PK_Reports_Documents)получу следующий результат для идентификатора отчета 18698:

введите описание изображения здесь

Для этого запроса:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

Я получаю план запроса, который включает поиск кластерного индекса, PK_Reports_Documentsкак и ожидалось.

Но то, что сбивает с толку меня, является неправильным значением для Предполагаемого количества строк:

введите описание изображения здесь

Согласно этому :

Когда значение примера предложения WHERE равно значению гистограммы RANGE_HI_KEY, SQL Server будет использовать столбец EQ_ROWS в гистограмме, чтобы определить количество строк, равное

Это также, как я ожидал бы, но это не так в реальной жизни. Я также попробовал некоторые другие RANGE_HI_KEYзначения, которые присутствовали в гистограмме, предоставленной show_statisticsи испытали то же самое. Эта проблема в моем случае, по-видимому, приводит к тому, что некоторые запросы используют очень неоптимальные планы выполнения, в результате чего время выполнения составляет несколько минут, тогда как я могу заставить его работать за 1 секунду с подсказкой запроса.

В целом: может кто-нибудь объяснить мне, почему EQ_ROWSиз гистограммы не используется для Расчетного количества строк и откуда берется неправильная оценка?

Немного больше (возможно, полезной) информации:

  • Автоматическое создание статистики включено, и вся статистика актуальна.
  • Запрашиваемая таблица содержит около 80 миллионов строк.
  • PK_Reports_Documentsпредставляет собой комбинацию ПК, состоящую из ReportID INTиDocumentID CHAR(8)

Похоже, что запрос загружает в общей сложности 5 различных объектов статистики, каждый из которых содержит ReportID+ некоторые другие столбцы из таблицы. Все они были недавно обновлены. RANGE_HI_KEYв таблице ниже приведено самое высокое значение верхнего столбца в гистограмме.

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  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 планируется запускать каждую ночь для обновления статистики.

user1151923
источник

Ответы:

10

Существует простое решение этого:

Отбросьте всю _dta_...статистику и прекратите слепо применять рекомендации DTA.

Дополнительная информация

Особая проблема заключалась в том, что для рассматриваемого столбца было несколько наборов статистики. Дополнительная dtaстатистика была создана путем выборки данных (поведение по умолчанию для статистики, не связанной с индексом).

Как это часто бывает с выборочной статистикой, полученные гистограммы не охватывали весь диапазон базовых данных. В результате запроса в вопросе было выбрано значение, которое находится за пределами гистограммы, что привело к оценке в 1 строку.

Точное поведение оптимизатора запросов при наличии нескольких наборов статистики для одного столбца не полностью задокументировано. Он, как правило, предпочитает статистику «полного сканирования» перед выборкой, но он также предпочитает более недавно обновленную статистику старшей.

Аарон Бертран
источник
Это действительно работает. Однако я не создавал _dta_статистику, они были там с тех пор, как я впервые увидел БД. Я не знал, что использование рекомендаций может иметь такие негативные последствия ...
user1151923 27.02.15