sql-server - 带排序的 SQL 实际执行计划成本高
问题描述
DocumentItem
我有一个名为Id
列的表是聚集索引(主键)。
请查看这两个查询字符串:
- 查询 1(不使用 order by):
select *
from DocumentItem
where (HistoryCreateDate >= '2019-09-04 05:00:00' AND HistoryCreateDate <= '2019-12-04 05:00:00') and ActNodeState>140100
结果是:00:00:09 有 168.357 行。
- 查询2(使用顺序):
select *
from DocumentItem
where (HistoryCreateDate >= '2019-09-04 05:00:00' AND HistoryCreateDate <= '2019-12-04 05:00:00') and ActNodeState>140100 order by Id
结果是:00:02:41 有 168.357 行。
这是实际的执行计划:
为什么在第二次查询中花了这么长时间?
解决方案
SQL Server 已确定您的索引 IX_HistoryCreateDate(不确定全名)具有足够的选择性,它将使用它来查找所需的行。但是,该索引未按 ID 列排序。它确实已经包含 ID 列(无论您是否指定它),因为它是集群键。
我建议像这样重新创建您的 IX_HistoryCreateDate 索引:
CREATE INDEX IX_HistoryCreateDate ON DocumentItem
( HistoryCreateDate, ID)
INCLUDE (ActNodeState);
我想你会没事的。它仍然不会很好,并且必须进行大量查找,因为您的查询使用 SELECT *。您真的需要返回所有列吗?如果是这样,并且您一直这样做,您可能会考虑按照您需要的顺序重新集群表。
推荐阅读
- r - ggplot2 堆积条形图 - 每个条为 100%,每个条内都有百分比标签
- javascript - 单元测试未定义不是对象(评估“this.groups.map”)
- javascript - 基于先前调用的响应的异步调用,避免回调地狱
- c# - 正则表达式验证 Windows UNC 路径
- java - 运行 mvn 原型时出错:生成
- c# - 使用动态注入类创建委托
- python - 将 Python str 转换为 C const char *
- c# - 如何为 C# 生成序列化器/反序列化器代码?
- java - Camel CxfEndpoint 拦截器失败
- thymeleaf - 带有迭代器的 Thymeleaf 条件