• 浅析 SQL Server 的 CROSS APPLY 和 OUTER APPLY 查询 - 第二部分


    CROSS APPLY 和 OUTER APPLY 示例

    上一篇文章介绍了 APPLY 运算符并介绍了它与常规 JOIN 的区别。在今天的后续文章中,我们将比较 APPLY 与 INNER JOIN 的性能,并学习如何将 APPLY 与表值函数一起使用。

    APPLY 和 INNER JOIN 比较

    回顾一下,在第 1 部分的末尾,我们运行了一个由两部分组成的查询:第一个查询从 Department 表中选择数据,并使用 CROSS APPLY 为 Department 表的每条记录对 Employee 表求值;第二个查询将 Department 表与 Employee 表联接起来以产生相同的结果:

    在 Navicat 中,我们可以点击“解释”按钮来获取有关数据库执行计划的有价值的信息。以下是关于上述查询的执行计划:

    尽管两个查询的执行计划相似且成本相同,但它们的执行计划确实有所不同:

    • APPLY 查询使用计算标量。它是一个运算符,用于通过执行产生计算值的标量计算操作从现有行值计算新值。这些标量计算包括标量值的转换或串联。请注意,计算标量运算符不是一个耗费大量资源的运算符,并且对我们查询的整体增加的成本非常小,能导致最小的开销。
    • JOIN 查询包含附加的聚集索引扫描。当 SQL Server 从上到下读取聚集索引中的行时(例如在非键列中搜索数据时),就会发生这种情况。这是一个比计算标量稍微成本高一些的操作。

    使用 APPLY 运算符联接表值函数和表

    表值函数是用户定义的函数,它返回表类型的数据。表值函数的返回类型是表,因此,你可以像使用表一样使用表值函数。将表值函数与其他表联接是 APPLY 运算符的设计目的。

    让我们创建一个表值函数,它接受一个 DepartmentID 作为其参数并返回属于该部门的所有员工。在 Navicat 中,我们可以通过点击主工具栏上的大函数按钮,然后点击功能工具栏上的新建函数来创建一个函数:

    这是单击“保存”按钮后的 GetAllEmployeesForDepartment 函数:

    看看当我们使用 CROSS OUTER 和 OUTER APPLY 将我们的新函数加入每个部门时会发生什么:

    在每种情况下,查询都会传递来自外部表表达式的每一行的 DepartmentID,并为每一行评估函数,类似于一个相关子查询。CROSS APPLY 仅返回相关数据,而 OUTER APPLY 也会返回非相关数据,这导致缺失列会显示 NULL。

    我们无法用 INNER JOIN/LEFT OUTER JOIN 替换上述查询中的 CROSS/OUTER APPLY。这样做会产生错误“The multi-part identifier "D.DepartmentID" could not be bound.”。这是因为外部(JOINed)查询的执行上下文与函数(或派生表)的执行上下文不同。因而,你不能将外部查询中的值或变量作为参数绑定到函数。因此,此类查询需要 APPLY 运算符。

    总结

    我们对 CROSS APPLY 和 OUTER APPLY 语句的研究到此结束。总而言之,你在查询中必须使用表值函数时,就需要使用 APPLY 运算符,但它也可以用于内联 SELECT 语句。如果你想试用 Navicat 16,可以在这里下载 Navicat 的 14 天全功能免费试用版。

    往期回顾

    Navicat 被投毒了 | 真相来了!

    Navicat 成为信通院数据库创新实验室成员

    Navicat 学术伙伴计划 - 免费教育版申请

    Navicat 技术智库 - 实战演练与各类热门问题解答

    免费试用攻略 | Navciat 16 数据库管理工具

  • 相关阅读:
    vscode输入英文时字体之间的间隔突然变大,似中文
    【Flink SQL】Flink SQL 基础概念(三):SQL 动态表 & 连续查询
    基于PHP的纺织用品商城系统
    Linux Control Cgroups
    [TOG2022]DCT-Net: Domain-Calibrated Translation for Portrait Stylization
    .NET应用如何防止被反编译
    Linux中的.bashrc文件
    导入JankStats检测卡帧库遇到问题记录
    深度学习笔记_1、定义神经网络
    Linux驱动开发笔记(六):用户层与内核层进行数据传递的原理和Demo
  • 原文地址:https://blog.csdn.net/weixin_53935287/article/details/125541781