首先,我正在使用:Microsoft SQL Server 2012(SP1) - 11.0.3000.0(X64)
我创建了一个如下所示的表:
create table dbo.pos_key
( keyid int identity(1,1) not null
, systemid int not null
, partyid int not null
, portfolioid int null
, instrumentid int not null
, security_no decimal(10,0) null
, entry_date datetime not null
)
keyid是一个群集主键。我的桌子有大约144,000行。目前systemId并没有太大的波动,除了1之外每行都是一样的。 现在我执行以下查询:
select *
from pos_key
where systemid = 33000
and portfolioid = 150444
and instrumentid = 639
在聚簇索引扫描后返回1行。 [pos_key]。[PK_pos_key] 执行计划表示预期行数为1.082
SQL Server很快建议我添加一个索引。
CREATE NONCLUSTERED INDEX IDX_SYS_PORT_INST
ON [dbo].[pos_key] ([systemid],[portfolioid],[instrumentid])
所以我再次运行查询。 令人惊讶的是,SQL服务器并没有使用新索引,而是再次使用相同的聚簇索引扫描,但现在它声称期望4087行!然而,这次并没有建议任何新的指数。
为了让它使用新索引,我已经完成了以下工作:
没有运气,SQL服务器总是用于集群扫描,并且需要4087行。
索引统计信息如下所示:
All Density Average Length Columns
----------------------------------------------------------------------------
0.5 4 systemid
6.095331E-05 7.446431 systemid, portfolioid
1.862301E-05 11.44643 systemid, portfolioid, instrumentid
6.9314E-06 15.44643 systemid, portfolioid, instrumentid, keyid
奇怪的是,我一夜之间离开了这个,早上再次运行查询,现在BAMM点击索引。我删除了索引,运行了选择,然后再次创建了索引。现在SQL服务器返回到4087预期行和聚簇索引扫描。
所以我错过了什么。该索引显然有效,但SQL服务器并不想立即使用它。
答案 0 :(得分:0)
使用复合索引和等式谓词中使用的所有列,首先指定最具选择性的列(此处为portfolieid
)。 SQL Server仅为第一列维护直方图。
首先使用选择性较低的列,SQL Server可能高估了行数,并选择了聚簇索引扫描,而不是认为它更有效,因为您选择了所有列。