SQL慢查询优化请求:耗时11分钟的查询性能提升方案
优化建议
1. 移除冗余的DISTINCT
原查询里的SELECT DISTINCT COUNT(*)完全没必要,COUNT(*)本身就是统计符合条件的总行数,DISTINCT在这里不会改变结果,反而会额外增加计算开销。直接改成:
SELECT COUNT(*)
2. 简化StationID的条件判断
把多个OR替换成IN子句,语法更简洁,也能让SQL Server查询优化器更容易生成高效执行计划:
ScanJobLog.StationID IN ('207', '208', '218', '219')
3. 创建针对性复合索引
这是提升性能最核心的一步。根据你的过滤逻辑,建议创建包含以下列的复合非聚集索引:
- 先放精确匹配的列:
StationID、ScanJobResult - 再放范围过滤列:
Occurred - 最后通过
INCLUDE包含Scan列(前缀匹配的LIKE可以利用索引)
创建索引的语句:
CREATE NONCLUSTERED INDEX IX_ScanJobLog_StationID_Result_Occurred_Scan ON [MyDataBase].[dbo].[ScanJobLog] (StationID, ScanJobResult, Occurred) INCLUDE (Scan);
索引列顺序很关键:等值匹配列在前,范围列在后,用INCLUDE包含需要的列能避免索引键值过大,提升索引效率。
4. 修正日期范围的边界问题
如果Occurred是datetime或datetime2类型,BETWEEN '2023-03-28' AND '2023-03-29'只会包含到2023-03-29 00:00:00的记录,要是你需要覆盖当天一整天的数据,改成下面的写法更准确,也能让索引更好地生效:
ScanJobLog.Occurred >= '2023-03-28' AND ScanJobLog.Occurred < '2023-03-30'
5. 额外检查项
- 更新表统计信息:执行
UPDATE STATISTICS [MyDataBase].[dbo].[ScanJobLog];,确保查询优化器能拿到最新的数据分布情况,生成更优的执行计划。 - 查看执行计划:在SSMS里按
Ctrl+L显示估计执行计划,要是看到表扫描或键查找这类操作,基本就是缺少合适索引的信号。
内容的提问来源于stack exchange,提问作者Emmanuel_InfTech
相关产品推荐
相关产品推荐

