优化含WHERE子句子查询的SQL Server查询执行计划
SQL Server子查询优化:让MAX(date)先计算再过滤
下面提供几种可行的优化方案,强制SQL Server先执行子查询获取最大日期,再用该值过滤table1的数据:
1. 用变量预存最大日期
先通过变量存储table2的最大日期,再用变量作为过滤条件,逻辑上明确先执行子查询:
DECLARE @MaxDate DATE; SELECT @MaxDate = MAX(date) FROM TABLE2; SELECT * FROM TABLE1 WHERE date < @MaxDate;
这种写法会让SQL Server优先计算MAX(date)并存在变量中,后续主查询直接使用这个固定值做过滤,执行计划会转为直接扫描/索引查找加过滤操作,不会生成内连接。
2. 使用CTE或派生表固定子查询结果
通过CTE或派生表先计算出单一的最大日期值,再与table1做关联过滤,引导优化器优先处理子查询:
CTE写法
WITH MaxDateCTE AS ( SELECT MAX(date) AS MaxDate FROM TABLE2 ) SELECT t1.* FROM TABLE1 t1 CROSS JOIN MaxDateCTE cte WHERE t1.date < cte.MaxDate;
派生表写法
SELECT t1.* FROM TABLE1 t1 CROSS JOIN (SELECT MAX(date) AS MaxDate FROM TABLE2) dt WHERE t1.date < dt.MaxDate;
由于子查询仅返回一行数据,CROSS JOIN相当于引入一个常量值,优化器会先计算该值,再对table1做过滤匹配。
3. 添加查询提示强制重新编译
如果不想修改查询结构,可在原语句末尾添加OPTION (RECOMPILE)提示,让优化器重新编译时识别子查询为单值常量:
SELECT * FROM TABLE1 WHERE date < (SELECT MAX(date) FROM TABLE2) OPTION (RECOMPILE);
RECOMPILE会让优化器重新生成执行计划,此时它会先计算子查询的MAX值并将其当作常量处理,从而生成过滤式的高效执行计划。
额外优化建议
给table2的date字段创建索引,可大幅提升MAX(date)的计算速度,进一步降低整体查询成本。
内容的提问来源于stack exchange,提问作者Sharad R. Telkar
相关产品推荐
相关产品推荐

