2016-08-10 87 views
1

問題與MS SQL Server 2008+有關。索引搜索估計行

有表(比如,5-10M行)

CREATE TABLE [Test].[Persons](
[PersonId] [int] NOT NULL, 
[FirstName] [varchar] (50) NOT NULL, 
[LastName] [varchar] (50) NOT NULL, 
[OtherNames] [varchar] (50) NULL, 
[BirthDate] [varchar] (10) NULL 
CONSTRAINT [PK_Persons] PRIMARY KEY CLUSTERED ([PersonId] ASC) 
) 

隨着指數

CREATE NONCLUSTERED INDEX [IX_Persons_LastName_FirstName] 
ON [Test].[Persons] ([LastName] ASC, [FirstName] ASC) 

執行簡單的查詢像

SELECT [FirstName],[LastName],[BirthDate] 
FROM [Test].[Persons] WHERE [LastName] = 'Decker' 

我看到,有索引查找運算符,當鍵不在統計學組態時是確切的值,估計的行嚴重不同於實際行。
對於某些特定的鍵,它可以是約15個估計行與10k個實際行。
似乎在這種情況下,「估計行數」值是直接從AVG_RANGE_ROWS獲取相應的時間間隔(即下一個直方圖數值)。

預期行爲?我的意思是,SQL Server是否「知道」該值不準確,並在計算查詢成本時使用這個事實,或者這是一個潛在的錯誤查詢計劃問題?

嘗試使用SQL2008R2,2012,2014(全部都使用OLD基數估計器)據我所知,只有在處理查詢中的多個表時,新CE纔會更改內容。嘗試有趣,但我還沒有。

+0

我想這是因爲統計樣本只猜測有多少DECKER你很可能有 - 嘗試一些常見和罕見的名字,看看是否有模式 – Cato

+0

嘗試運行UPDATE STATISTICS –

+0

@Tab Alleman統計信息在查詢執行之前用FULLSCAN更新。 – Marvin

回答

0

我在這個問題上做了一些工作,並明確表示。

簡短回答:好吧,對我感到羞恥。這正是統計數據的工作原理。在我的情況下,額外的過濾統計數據會勝出感謝您的評論,它們對於開始檢查非常有用。

長答案: 「問題」是在密鑰分配數據。我已經在填充直方圖的所有200個步驟,它不能收集有關確切的常見值的更多信息。超過50萬的相對罕見的獨特價值,它顯然(現在對我來說)的影響。

我做一個簡單的例子腳本,顯示出類似的行爲:

CREATE TABLE [TestStatistics] (
[Id] [INT] IDENTITY (1,1) PRIMARY KEY, 
[Val] [INT] NOT NULL 
) 
GO 
--Insert 200k rows with ~60k distinct values 
insert into TestStatistics (Val) VALUES (CHECKSUM (newid())%30000) 
go 200000 
--Insert 100k rows with ~600 distinct values, that are multiples of 100 
insert into TestStatistics (Val) VALUES (CHECKSUM (newid())%300*100) 
GO 100000 

create nonclustered index IX_TestStatistics_Val on TestStatistics(Val ASC) 
GO 

因此,我已插入300K總行用〜60K的不同值,這意味着在所述表中的密度〜0.2。而且我有「特殊的」100k行,填充了600個不同的值--100的倍數。也就是說,這些行中的任何行都會遇到~166次。 和統計,現在正在尋找這樣的:

Statistics

現在,如果我參加任何100的倍數,這在直方圖不存在(例如,7500),我會得到估計4.5-5.5行將近166實際行。估計值實際上是直方圖中的下一個AVG_RANGE_ROWS值(對於7500 - 在Val = 7800處)。現在

,如果我收集一些額外的統計資料,例如

CREATE STATISTICS ST_TestStatistics_0_10000 
ON TestStatistics(Val) WHERE Val>=0 AND Val<10000 

我會得到另一種查詢計劃:

Query Plans