Я выполняю этот запрос в базе данных AdventureWorks2012 :
SELECT
s.SalesOrderID,
d.CarrierTrackingNumber,
d.ProductID,
d.OrderQty
FROM Sales.SalesOrderHeader s
JOIN Sales.SalesOrderDetail d
ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077
Если я посмотрю на примерный план выполнения, я увижу следующее:
Первоначальный поиск по индексу (вверху справа) использует индекс IX_SalesOrderHeader_CustomerID и осуществляет поиск по литералу 11077. Его оценка составляет 2,6192 строки.
Если я использую DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM
, это показывает, что значение 11077 находится между двумя выбранными ключами 11019 и 11091.
Среднее число отдельных строк между 11019 и 11091 составляет 2,619718 или округлено до 2,61972, что является значением оценочных строк, показанных для поиска по индексу.
Часть, которую я не понимаю, - это приблизительное количество строк для поиска кластеризованного индекса по таблице SalesOrderDetail.
Если я бегу DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID')
:
Таким образом, плотность SalesOrderID (к которому я присоединяюсь) составляет 3.178134E-05. Это означает, что 1 / 3.178134E-05 (31465) равно количеству уникальных значений SalesOrderID в таблице SalesOrderDetail.
Если в SalesOrderDetail имеется 31465 уникальных SalesOrderID, то при равномерном распределении среднее число строк на SalesOrderID равно 121317 (общее количество строк), деленное на 31465. Среднее значение составляет 3.85561.
Таким образом, если предполагаемое количество строк, подлежащих циклу, равно 2,61972, а среднее значение, которое должно быть возвращено в 3,85561, я думаю, что предполагаемое количество строк будет 2,61972 * 3,85561 = 10,10062.
Но предполагаемое количество строк - 11,4867.
Я думаю, что мое понимание второй оценки неверно, и разные цифры, кажется, указывают на это. Что мне не хватает?