You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化SQL Server查询?耗时5-7分钟求提速方案

SQL Server 查询性能优化方案

一、修复WHERE子句的非SARGable问题

原查询中CAST(table2.record AS DATE)会直接导致索引失效,因为对列进行了函数转换。根据table2.record的字段类型调整:

  • 如果是datetime/datetime2类型:直接用日期范围匹配,避免函数转换
WHERE table2.record >= '2023-03-01 00:00:00'
  AND table2.record < '2023-03-06 00:00:00'
  • 如果是字符串类型:优先将字段改为datetime类型(长期优化),临时方案可提前转换查询参数,但改字段类型是最优解。

二、重构JOIN条件,消除性能杀手

原JOIN条件的字符串拼接+OR逻辑完全无法利用索引,可通过以下两种方式优化:

方案1:拆分JOIN并使用UNION ALL合并

将OR逻辑拆分为两个独立的INNER JOIN,用UNION ALL避免去重开销(若有重复结果再换UNION):

SELECT DISTINCT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2 ON t1.record = CONCAT(t2.col1, ',', t2.col2)
WHERE t2.record >= '2023-03-01 00:00:00'
  AND t2.record < '2023-03-06 00:00:00'
UNION ALL
SELECT DISTINCT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2 ON t1.record = CONCAT(t2.col1, ',', t2.col2, ',', t2.col3)
WHERE t2.record >= '2023-03-01 00:00:00'
  AND t2.record < '2023-03-06 00:00:00'

方案2:新增持久化计算列并建立索引(长期最优)

在table2中提前计算拼接好的字符串,创建持久化计算列后建立复合索引:

-- 创建持久化计算列
ALTER TABLE table2 ADD col1_col2 AS CONCAT(col1, ',', col2) PERSISTED;
ALTER TABLE table2 ADD col1_col2_col3 AS CONCAT(col1, ',', col2, ',', col3) PERSISTED;

-- 建立包含必要字段的复合索引
CREATE NONCLUSTERED INDEX IX_table2_col1_col2_record 
ON table2 (col1_col2, record) 
INCLUDE (col1, col2, col3 /*其他需要返回的列*/);

CREATE NONCLUSTERED INDEX IX_table2_col1_col2_col3_record 
ON table2 (col1_col2_col3, record) 
INCLUDE (col1, col2, col3 /*其他需要返回的列*/);

优化后的查询语句:

-- 只返回需要的列,避免SELECT *
SELECT t1.id, t1.record, t2.col1, t2.col2, t2.col3
FROM table1 t1
INNER JOIN table2 t2 
  ON t1.record = t2.col1_col2 
  OR t1.record = t2.col1_col2_col3
WHERE t2.record >= '2023-03-01 00:00:00'
  AND t2.record < '2023-03-06 00:00:00'

三、避免SELECT *,按需返回列

SELECT *会返回所有字段,包括大文本、二进制类型,大幅增加磁盘IO和网络传输开销。明确写出需要的列,减少不必要的数据读取。

四、优化table1的索引

确保table1的record字段有非聚集索引,匹配JOIN条件:

CREATE NONCLUSTERED INDEX IX_table1_record 
ON table1 (record) 
INCLUDE (/*需要返回的列*/);

五、用执行计划定位剩余瓶颈

在SQL Server Management Studio中按Ctrl+M开启实际执行计划,查看:

  • 是否存在表扫描/聚集索引扫描(说明索引未被有效利用)
  • 等待类型(比如PAGEIOLATCH_*表示磁盘IO不足,CXPACKET表示并行执行存在问题)

内容的提问来源于stack exchange,提问作者Jhonn Matthew Calvelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 16:07:30