通过PK列进行排序时SQL查询速度很慢

时间:2014-05-21 15:01:57

标签: sql sql-server sql-server-2008

为什么此查询需要很长时间(30秒以上)才能运行?

A:

SELECT TOP 10 * FROM [Workflow] ORDER BY ID DESC

但是这个查询很快(0秒):

B:

SELECT TOP 10 * FROM [Workflow] ORDER BY ReadTime DESC

这也很快(0秒):

C:

SELECT TOP 10 * FROM [Workflow] WHERE SubId = '120611250634'

我明白为什么B和C很快:

B:
enter image description here

C:
enter image description here

但是我不明白为什么A需要这么长时间才有这个:

enter image description here

编辑:使用ID:

估算的执行计划

enter image description here

编辑:使用ReadTime的估计执行计划:

enter image description here

2 个答案:

答案 0 :(得分:3)

好吧,您的主键是 ID(ASC)和ReadTime(ASC)。当您只有一个列索引时,顺序并不重要,但是当索引中有更多列(复合键)时,它就很重要。

复合群集密钥并非真正用于排序。我希望使用

SELECT TOP 10 * FROM [Workflow] ORDER BY ID ASC

会相当快,最好的是

SELECT TOP 10 * FROM [Workflow] ORDER BY ID, ReadTime

撤销订单对复合键来说是一项棘手的操作。

因此,当您按ReadTime订购时,您已准备好索引,并且该索引还知道所涉及行的确切密钥(Id和{{1} - 保持聚簇索引非常窄的另一个好理由)。它可以很容易地查找所有列。但是,当您按ReadTime订购时,您并不完全符合索引。服务器并不能轻易知道给定Id有多少行,这意味着Id比你想象的要复杂一些。实际上,您的聚簇索引会浪费空间和性能(就这些示例查询而言)。

只看到数据库的一小部分,我会说在Id和ReadTime上有一个聚簇索引是一个坏主意。你为什么这样做?

答案 1 :(得分:1)

看起来ID本身并不是PK,而是ReadTime(基于你的第3张照片)。

因此,索引建立在(ID,ReadTime)对上,您的查询不会使用此索引。

尝试仅在ID上添加索引。