为什么我的主键减慢了查询速度?

时间:2009-06-08 10:16:34

标签: sql-server performance indexing

我正在使用SQL Server 2008,并且在我的一个表中,我在其标识符上实现了(群集)主键。这是表格描述:

标识符:   - IdentifierId int NOT NULL PK   - Alias nvarchar(200)   - DataType int NOT NULL

我制作了两个索引:一个用于Alias,另一个用于DataType。 但是,我刚注意到一些奇怪的事情。 运行以下查询时:

SELECT * FROM IDENTIFIER WHERE DataType = 1

查询实际上使用索引和主键运行速度比没有它们时要慢;它需要大约10秒钟!索引没有碎片 - 我检查 - 我也在使用这个

GO
CHECKPOINT;
GO
DBCC DROPCLEANBUFFERS;
GO
DBCC FREEPROCCACHE;
GO
在查询本身之前

此表相当大,上面有数百万个条目。索引和PK在大多数查询中起着至关重要的作用,但在这种情况下,我无法理解为什么查询与它们一起运行较慢。有什么想法吗?

提前致谢

编辑:执行计划显示仅使用聚集索引,并且DataType变量当前最多为150。

2 个答案:

答案 0 :(得分:7)

当您选择*时,系统仍需要获取每一列。因此优化器通常会确定使用聚簇索引扫描更快(记住聚簇索引实际上不是索引 - 它只是按指定顺序组织的数据),而不是使用不同索引上的搜索结合书签查找基于主键来检索其他行。

因此,性能的关键是拥有一个非聚集索引(这是一个错误的名称,实际上,因为非聚簇索引通常远远超过聚簇索引)和索引中的INCLUDE个额外列,所以它变为covering。对于SQL Server 2005之前的版本,您只需将列添加到索引的末尾。

因此,基本上,主键是好的,但不一定决定您选择的群集,并且通常需要依赖非聚集索引(具有适当的INCLUDE ed列)来提高性能选择性操作,聚集索引是为最少选择性和最常排序的情况而设计的。

答案 1 :(得分:5)

DataType上创建包含列Alias的复合非群集覆盖索引,并删除AliasDataType列上的各个索引:

CREATE NONCLUSTERED INDEX NC_DataType_I_Alias 
    ON tblIdentifier(DataType) INCLUDE (Alias)