Sql-Server

>= 和 > 的基數估計,用於步內統計值

  • April 10, 2017

我試圖了解 SQL Server 如何嘗試估計 SQL Server 2014 中的“大於”和“大於等於”where 子句。

我想我確實理解了基數估計,例如,如果我這樣做了

   select * from charge where charge_dt >= '1999-10-13 10:47:38.550'

基數估計是 6672,可以很容易地計算為 32(EQ_ROWS) + 6624(RANGE_ROWS) + 16 (EQ_ROWS) = 6672(下面截圖中的直方圖)

在此處輸入圖像描述

但是當我這樣做時

   select * from charge where charge_dt >= '1999-10-13 10:48:38.550' 

(將時間增加到 10:48 所以它不是一個步驟)

估計是 4844.13。

那是怎麼計算的?

唯一的困難是決定如何處理查詢謂詞區間**部分覆蓋的直方圖步驟。**如問題中所述,謂詞範圍涵蓋的整個直方圖步驟是微不足道的。

傳統基數估計器

F= 查詢謂詞所涵蓋的步長范圍的分數(介於 0 和 1 之間)。

基本思想是使用F(線性插值)來確定謂詞覆蓋了多少步內不同值。將此結果乘以每個不同值的平均行數(假設均勻),然後將步長相等的行相加,得出基數估計:

基數 = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)

相同的公式用於>>=在舊版 CE 中。

新基數估計器

新的 CE 稍微修改了之前的算法以區分>>=

首先>,公式為:

基數 = EQ_ROWS + (AVG_RANGE_ROWS * (F * (DISTINCT_RANGE_ROWS - 1)))

因為>=它是:

基數 = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))

+ 1反映了當比較涉及相等時,假設匹配(包含假設)。

在問題範例中,F可以計算為:

DECLARE 
   @Q datetime = '1999-10-13T10:48:38.550',
   @K1 datetime = '1999-10-13T10:47:38.550',
   @K2 datetime = '1999-10-13T10:51:19.317';

DECLARE
   @QR float = DATEDIFF(MILLISECOND, @Q, @K2), -- predicate range
   @SR float = DATEDIFF(MILLISECOND, @K1, @K2) -- whole step range

SELECT
   F = @QR / @SR;

結果是0.728219019233034>=將其代入其他已知值的公式中:

基數 = EQ_ROWS + (AVG_RANGE_ROWS * ((F * (DISTINCT_RANGE_ROWS - 1)) + 1))
= 16 + (16.1956 * ((0.728219019233034 * (409 - 1)) + 1))
= 16 + (16.1956 * ((0.728219019233034 * 408) + 1))
= 16 + (16.1956 * (297.113359847077872 + 1))
= 16 + (16.1956 * 298.113359847077872)
= 16 + 4828.1247307393343837632
= 4844.1247307393343837632
= **4844.12473073933**(浮點精度)

該結果與問題中顯示的 4844.13 的估計值一致。

使用舊版 CE 的相同查詢(例如使用跟踪標誌 9481)應產生以下估計:

基數 = EQ_ROWS + (AVG_RANGE_ROWS * F * DISTINCT_RANGE_ROWS)
= 16 + (16.1956 * 0.728219019233034 * 409)
= 16 + 4823.72307468722
= **4839.72307468722**

>請注意,對於和>=使用舊版 CE ,估計值是相同的。

引用自:https://dba.stackexchange.com/questions/148523