CURRENT_TIMESTAMP子查询写法的优势、查询性能对比及更优关联方式咨询
CURRENT_TIMESTAMP子查询写法的优势、查询性能对比及更优关联方式咨询
嘿,我来帮你拆解下这两个查询的问题:
性能对比:第一个查询不会比第二个更高效
这两个查询的逻辑完全等价,SQL Server的查询优化器会自动识别第一个查询里那个JOIN (SELECT CURRENT_TIMESTAMP as CURR_DTM) AS DTM ON 1 = 1的写法本质上是引入一个单一行的数据集,最终会把它优化成直接使用CURRENT_TIMESTAMP常量,和第二个查询的执行逻辑几乎没有区别。这也是你得到相同结果的原因——优化器已经帮你把冗余的关联去掉了。
如果想在SSMS里验证性能差异,可以这样做:
- 开启实际执行计划(点击工具栏的“包含实际执行计划”按钮,或按
Ctrl+M),执行两个查询后对比计划,你会发现它们的执行步骤完全一致。 - 执行
SET STATISTICS TIME, IO ON;,然后运行两个查询,查看输出的CPU时间、逻辑读等指标,就能确认性能没有差异。
替代1=1的更优关联方式
用1=1来关联单一行子查询虽然能跑通,但语义不够清晰,有几种更规范的写法:
1. 使用CROSS JOIN
因为这个子查询只返回一行数据,CROSS JOIN是语义上最准确的写法,不需要额外的ON条件:
SELECT s.StudentId, count(*) as SchoolCount FROM Student as s CROSS JOIN (SELECT CURRENT_TIMESTAMP as CURR_DTM) AS DTM JOIN StudentSchool ss ON ss.StudentId = s.StudentId AND (ss.StartDtm < CURR_DTM) AND (ss.EndDtm IS NULL OR ss.EndDtm > CURR_DTM) GROUP BY s.StudentId
2. 用CTE定义时间戳
如果后续查询逻辑更复杂,或者需要多次复用这个时间值,用CTE会让结构更清晰:
WITH DTM AS ( SELECT CURRENT_TIMESTAMP as CURR_DTM ) SELECT s.StudentId, count(*) as SchoolCount FROM Student as s CROSS JOIN DTM JOIN StudentSchool ss ON ss.StudentId = s.StudentId AND (ss.StartDtm < CURR_DTM) AND (ss.EndDtm IS NULL OR ss.EndDtm > CURR_DTM) GROUP BY s.StudentId
3. 定义局部变量(SQL Server专属)
如果希望时间值只计算一次(虽然优化器通常也会自动处理CURRENT_TIMESTAMP的单次求值),可以用变量:
DECLARE @CURR_DTM DATETIME = CURRENT_TIMESTAMP; SELECT s.StudentId, count(*) as SchoolCount FROM Student as s JOIN StudentSchool ss ON ss.StudentId = s.StudentId AND (ss.StartDtm < @CURR_DTM) AND (ss.EndDtm IS NULL OR ss.EndDtm > @CURR_DTM) GROUP BY s.StudentId
备注:内容来源于stack exchange,提问作者user10223479
相关产品推荐
相关产品推荐

