2016-08-10 89 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