加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql-server – 检查是否存在EXISTS优于COUNT! ……不是吗?

发布时间:2021-03-14 21:05:55 所属栏目:MsSql教程 来源:网络整理
导读:副标题#e# 我经常阅读当必须检查行的存在时,应始终使用EXISTS而不是COUNT. 然而,在最近的几个场景中,我测量了使用计数时的性能提升. 模式如下: LEFT JOIN ( SELECT someID,COUNT(*) FROM someTable GROUP BY someID) AS Alias ON ( Alias.someID = mainTab

显示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,并且性能受到合并半连接的探测端没有搜索的影响,您可以考虑使用产生正确结果的不同语法编写查询更有效的执行计划.

(编辑:云计算网_泰州站长网)

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

推荐文章
    热点阅读