Формула для оценки строк становится немного глупой, когда фильтр «больше чем» или «меньше чем», но это число, к которому вы можете прийти.
Числа
Используя шаг 193, вот соответствующие цифры:
RANGE_ROWS = 6624
EQ_ROWS = 16
AVG_RANGE_ROWS = 16.1956
RANGE_HI_KEY из предыдущего шага = 1999-10-13 10: 47: 38.550
RANGE_HI_KEY из текущего шага = 1999-10-13 10: 51: 19.317
Значение из предложения WHERE = 1999-10-13 10: 48: 38.550
Формула
1) Найдите мс между двумя клавишами диапазона hi
SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')
Результат - 220767 мс.
2) Отрегулируйте количество рядов
Нам нужно найти строки в миллисекунду, но прежде чем мы это сделаем, мы должны вычесть AVG_RANGE_ROWS из RANGE_ROWS:
6624 - 16,1956 = 6607.8044 строки
3) Рассчитать количество строк в мс с заданным количеством строк:
6607.8044 строк / 220767 мс = .0299311 строк в мс
4) Рассчитать мс между значением из предложения WHERE и текущим шагом RANGE_HI_KEY
SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')
Это дает нам 160767 мс.
5) Рассчитайте строки в этом шаге на основе строк в секунду:
.0299311 строк / мс * 160767 мс = 4811,9332 строки
6) Помните, как мы вычитали AVG_RANGE_ROWS ранее? Время добавить их обратно. Теперь, когда мы закончили вычисление чисел, связанных со строками в секунду, мы также можем безопасно добавить EQ_ROWS:
4811,9332 + 16,1956 + 16 = 4844,1288
В итоге это наша оценка 4844,13.
Тестирование формулы
Я не смог найти ни одной статьи или поста в блоге о том, почему AVG_RANGE_ROWS вычитается до того, как вычисляются строки в мс. Я был в состоянии подтвердить , что они учитываются в оценке, но только в последнюю миллисекунду - в буквальном смысле.
Используя базу данных WideWorldImporters , я провел некоторое инкрементное тестирование и обнаружил, что уменьшение оценок строк будет линейным до конца шага, где внезапно учитывается 1x AVG_RANGE_ROWS.
Вот мой пример запроса:
SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'
Я обновил статистику для PickingCompleted, когда, а затем получил гистограмму:
DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')
Чтобы увидеть, как уменьшаются оценочные строки при приближении к RANGE_HI_KEY, я собирал выборки на протяжении всего шага. Уменьшение является линейным, но ведет себя так, как будто число строк, равное значению AVG_RANGE_ROWS, просто не является частью тренда ... пока вы не нажмете RANGE_HI_KEY, и вдруг они упадут, как списанный непогашенный долг. Вы можете увидеть это на примере данных, особенно на графике.
Обратите внимание на устойчивый спад в строках, пока мы не нажмем на RANGE_HI_KEY, а затем на BOOM, из которого неожиданно вычитается последний кусок AVG_RANGE_ROWS. Это легко заметить и на графике.
Подводя итог, странная обработка AVG_RANGE_ROWS усложняет вычисление оценок строк, но вы всегда можете согласовать действия CE.
Как насчет экспоненциального отката?
Экспоненциальный откат - это метод, который новый (начиная с SQL Server 2014) оценщик кардинальности использует для получения более точных оценок при использовании нескольких статистических данных за один столбец. Поскольку этот вопрос касался одного столбца stat, он не включает формулу EB.