【发布时间】:2018-12-13 21:01:17
【问题描述】:
我有一个简单的查询,但我不明白顶部子句的行为。
SELECT Top (1) Timestmp
FROM DataTable
WHERE [LoadId] = 3104
AND [Temp1] > @Setpoint
AND [Temp2] > @Setpoint
AND [Temp3] > @Setpoint
AND [Temp4] > @Setpoint
AND [Temp5] > @Setpoint
ORDER BY Timestmp OPTION (RECOMPILE)
(*查询是执行计划中的一个更简单的版本,但完全相同)
-
(LoadId, Temp1, Temp2, Temp3, Temp4, Temp5)上有一个通用的非聚集索引 - 以及
Timestmp上的单独非聚集索引
查询大约需要 1 分钟才能完成。但如果我写 Top (100) 则需要一些 [ms] 才能完成。
以下是查询的一些统计数据:
- 顶部 (1):逻辑读取 25757671,物理读取 148582,预读读取 17695
- Top (100):逻辑读取 290703,物理读取 0,预读读取 0
顶部(1):https://www.brentozar.com/pastetheplan/?id=B1zwx0klN
前 (100) 位:https://www.brentozar.com/pastetheplan/?id=Hkx5k0JgE
我怎样才能像 Top (100) 一样快地获得 Top (1),为什么这么慢?我以前从未在其他服务器上看到过这种行为,可能是 SQLServer 设置有问题?
【问题讨论】:
-
将您的计划 xml 上传到 brentozar.com/pastetheplan,而不是图像,并将链接添加到您的问题。另外,上传
TOP (100)计划。 -
请include the actual Execution Plan,您可以使用Paste the Plan 并在您的问题中分享链接。对两个查询(前 1 个和前 100 个)都执行此操作。
-
您的 top(100) 查询似乎运行聚集索引扫描而不是扫描+查找。由于使用缓冲区而不进行物理读取,因此速度更快。
-
您应该查看 SSMS 执行计划窗口中的绿色信息消息 - 它告诉您缺少一个索引,这会减少 90% 以上的查询时间 - 检查一下!
-
谢谢 marc_s 那是解决方案 :) 已经用 INCLUDE Timestmp 创建了一个索引,现在使用 top (1) 也很快
标签: sql-server