加入收藏 | 设为首页 | 会员中心 | 我要投稿 厦门网 (https://www.xiamenwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

sql-server – 为什么在SQL Server 2012中设置空结果的查询错误

发布时间:2021-03-18 18:25:12 所属栏目:编程 来源:网络整理
导读:在MS SQL Server 2012中运行以下查询时,第二个查询失败但不是第一个查询失败.此外,在没有where子句的情况下运行时,两个查询都将失败.我不知道为什么要么失败,因为两者都应该有空的结果集.任何帮助/见解表示赞赏. create table #temp(id int primary key)creat

在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

现在,第一个计划还包含一个常量表达式引用,并且两个查询都会生成错误消息.第一个查询的XML包含:

更多信息:Compute Scalars,Expressions and Performance

(编辑:厦门网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读