我有一个名为Workflow的表。表中有38M行。以下栏目中有一个PK:
ID: Identity Int
ReadTime: dateTime
如果我执行以下查询,则不使用PK。查询计划显示正在对其中一个非聚簇索引执行的索引扫描以及排序。 38M行需要很长时间。
Select TOP 100 ID From Workflow
Where ID > 1000
Order By ID
但是,如果我执行此查询,则使用非聚集索引(在LastModifiedTime上)。查询计划显示正在执行的索引查找。查询非常快。
Select TOP 100 * From Workflow
Where LastModifiedTime > '6/12/2010'
Order By LastModifiedTime
所以,我的问题是这个。为什么不在第一个查询中使用PK,而是使用第二个查询中的非聚簇索引?
答案 0 :(得分:2)
由于Id是一个标识列,因此让ReadTime参与索引是多余的。聚簇键已指向叶数据。我建议你修改索引
CREATE TABLE Workflow
(
Id int IDENTITY,
ReadTime datetime,
-- ... other columns,
CONSTRAINT PK_WorkFlow
PRIMARY KEY CLUSTERED
(
Id
)
)
CREATE INDEX idx_LastModifiedTime
ON WorkFlow
(
LastModifiedTime
)
另外,请检查统计信息是否是最新的。
最后,如果此表中有3800万行,则优化程序可能会认为指定条件>独特列上的1000是非选择性的,因为> 99.997%的Ids> 1000(如果您的身份种子从1开始)。为了使索引有用,优化器必须得出结论<将选择5%的记录。您可以使用索引提示强制解决问题(如Dan Andrews所述)。扫描的非聚集索引的结构是什么?
答案 1 :(得分:1)
无法在您的数据库中搜寻,我想到了一些事情。
(id, ReadTime)
而不是(ReadTime, id)
吗? SELECT MAX(id) FROM WorkFlow
执行的执行计划是什么? (id, ReadTime)
上创建索引,然后重试测试或查询,该怎么办?