在MS sql Server 2012中运行以下查询时,第二个查询失败但不是第一个查询失败.此外,在没有where子句的情况下运行时,两个查询都将失败.我不知道为什么要么失败,因为两者都应该有空的结果集.任何帮助/见解表示赞赏.
create table #temp (id int primary key) create table #temp2 (id int) select 1/0 from #temp where id = 1 select 1/0 from #temp2 where id = 1
解决方法
初步了解执行计划显示表达式1/0在Compute Scalar运算符中定义:
现在,即使执行计划确实在最左边开始执行,迭代地调用子迭代器上的Open和GetRow方法来返回结果,sql Server 2005及更高版本包含一个优化,表达式通常只由计算标量定义,使用evaluation deferred until a subsequent operation requires the result:
在这种情况下,仅在组装行以返回到客户端时才需要表达式结果(您可以将其视为在绿色SELECT图标处发生).根据该逻辑,延迟评估意味着永远不会评估表达式,因为两个计划都不会生成返回行.为了解决这一问题,Clustered Index Seek和Table Scan都没有返回一行,因此没有可以组装的行来返回客户端.
但是,有一个单独的优化,其中一些表达式可以标识为runtime constants,因此在查询执行开始之前评估一次.在这种情况下,可以在showplan XML(左侧的Clustered Index Seek计划,右侧的Table Scan计划)中找到已发生的指示:
我写了更多关于底层机制以及它们如何影响性能的更多内容in this blog post.使用那里提供的信息,我们可以修改第一个查询,以便在执行开始之前评估和缓存两个表达式:
select 1/0 * CONVERT(integer,@@DBTS) from #temp where id = 1 select 1/0 from #temp2 where id = 1