sql-server – 检查是否存在EXISTS优于COUNT! ……不是吗?
|
显示EXISTS测试的输入树的一部分如下所示: ScaOp_Exists
LogOp_Project
LogOp_Select
LogOp_Get TBL: #T2
ScaOp_Comp x_cmpEq
ScaOp_Identifier [T2].ID
ScaOp_Identifier [T1].ID
这由RemoveSubqInPrj转换为以下结构: LogOp_Apply (x_jtLeftSemi probe PROBE:COL: Expr1008) 这是左半连接应用前面描述的探针.此初始转换是迄今为止SQL Server查询优化器中唯一可用的转换,如果禁用此转换,编译将失败. 此查询的可能执行计划形状之一是该逻辑结构的直接实现: 最终的Compute Scalar使用探测列值评估CASE表达式的结果: 当优化考虑半连接的其他物理连接类型时,将保留计划树的基本形状.只有合并连接支持探测列,因此不考虑逻辑上可能的散列半连接: 请注意,合并输出一个标记为Expr1008的表达式(名称与之前的名称相同是巧合),但计划中的任何运算符都没有定义.这只是探测列.和以前一样,最终的Compute Scalar使用此探测值来评估CASE. 问题是优化器没有完全探索只有合并(或散列)半连接才有用的替代方案.在嵌套循环计划中,检查T2中的行是否与每次迭代的范围匹配没有任何好处.使用合并或哈希计划,这可能是一个有用的优化. 如果我们在查询中向T2添加匹配的BETWEEN谓词,那么所有发生的事情都是对每一行执行此检查作为合并半连接上的残差(很难在执行计划中找到,但它就在那里): SELECT
T1.ID,CASE
WHEN EXISTS
(
SELECT 1
FROM #T2 AS T2
WHERE T2.ID = T1.ID
AND T2.ID BETWEEN 5000 AND 7000 -- New
) THEN 1
ELSE 0
END AS DoesExist
FROM #T1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000;
我们希望BETWEEN谓词会被推迟到T2导致搜索.通常,优化器会考虑这样做(即使查询中没有额外的谓词).它识别隐含的谓词(T1上的BETWEEN和T1和T2之间的连接谓词一起暗示T2上的BETWEEN),而原始查询文本中不存在它们.不幸的是,apply-probe模式意味着没有探索. 有一些方法可以编写查询以在合并半连接的两个输入上产生搜索.一种方法是以非常不自然的方式编写查询(打败我通常更喜欢EXISTS的原因): WITH T2 AS
(
SELECT TOP (9223372036854775807) *
FROM #T2 AS T2
WHERE ID BETWEEN 5000 AND 7000
)
SELECT
T1.ID,DoesExist =
CASE
WHEN EXISTS
(
SELECT * FROM T2
WHERE T2.ID = T1.ID
) THEN 1 ELSE 0 END
FROM #T1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000;
我不满意在生产环境中编写该查询,只是为了证明所需的计划形状是可能的.如果您需要编写的真实查询以这种特定方式使用CASE,并且性能受到合并半连接的探测端没有搜索的影响,您可以考虑使用产生正确结果的不同语法编写查询更有效的执行计划. (编辑:天瑞地安资讯网_黄海网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- sql-server – 使用WITH REPLACE恢复备份时出现错误3154
- sql-server – 如果是肯定的,请汇总所有项目.如果是负数,则
- SQL * Plus不执行SQL Developer所执行的SQL脚本
- Linq选择记录范围
- sql – 查找值并显示找到的值的数据库,表,列,主键
- sql-server – 如何确定服务器上是否正在使用SQL Server ld
- sql – 具有动态文件名的COPY
- sql-server – 高效的事务,记录锁定
- sql-server-2008 – 如何在SQL Server 2008上找到内存压力故
- alter table alter SQL的SQL Server性能更改数据类型
- sql-server – IntelliSense无法正常工作但已启用
- sql-server – 是否可以使用存储过程获取mac地址
- SQL主键 – 是否有必要?
- sql-server – 来自不同进程中相同临时表的锁的死
- sql – 将pg_try_advisory_xact_lock()放在嵌套的
- sql-server-2005 – 为什么SQL Server在运行参数
- sql server将datetime转换为另一个时区?
- sql – 在视图中转换科学记数法(来自varchar –
- 数据库delete误删数据如何恢复?
- sql-server-2005 – IIS7上对SQL Server Reporti


