SQL Server不使用建议的索引

时间:2017-11-29 01:58:21

标签: sql-server indexing querying

首先,我正在使用: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行!然而,这次并没有建议任何新的指数。

为了让它使用新索引,我已经完成了以下工作:

  • 更新了表统计信息(更新统计信息)
  • 更新了索引统计信息(更新统计信息)
  • 与此查询相关的已删除缓存执行计划(DBCC FREEPROCCACHE)

没有运气,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服务器并不想立即使用它。

  • systemId的波动是否会以某种方式造成麻烦?
  • DBCC FREEPROCCACHE不足以摆脱缓存的执行计划吗?
  • SQL-Server的方式是不是很神秘?

1 个答案:

答案 0 :(得分:0)

使用复合索引和等式谓词中使用的所有列,首先指定最具选择性的列(此处为portfolieid)。 SQL Server仅为第一列维护直方图。

首先使用选择性较低的列,SQL Server可能高估了行数,并选择了聚簇索引扫描,而不是认为它更有效,因为您选择了所有列。