当前位置: 首页 > article >正文

SQL Server执行计划的步骤对应于查询优化器执行给定SQL查询的部分和优化策略

在SQL Server中,执行计划 是 SQL Server 用于执行查询的详细路线图。查询的每个部分对应于执行计划中反映的不同操作。了解这些操作有助于优化查询。
要优化查询,目标是尽早减少执行计划中处理的行数,并确保 SQL Server 可以有效地利用可用索引和联接策略。
以下是执行计划中关键步骤的细分以及每个步骤的常见优化策略:

1.FROM 子句

  • 对应的执行计划步骤:

    • 扫描操作(Table Scan、Index Scan 等)
    • SQL Server 必须找到需要处理的数据。如果没有可以提供帮助的索引,它可能会执行 Table Scan,或者如果可以从索引中检索数据,它可能会使用 Index Scan
  • 优化策略:

    • 索引: 确保为 WHERE、JOIN 和 ORDER BY 子句中使用的列创建适当的索引。
    • 覆盖索引: 使用覆盖索引(包含查询所需的所有列的索引)来避免键查找。
    • 分区: 如果您正在处理大型数据集,请考虑对大型表进行分区。
    • 避免全表扫描:使用选择性索引来避免全表扫描,尤其是在查询大型表时。

2.WHERE 子句

  • 对应的执行计划步骤:

    • 查找操作: 如果使用索引可以满足条件,SQL Server 可能会执行 索引查找。如果没有可用的索引,它可能会执行 Table ScanClustered Index Scan
    • Filter 运算符: 在从表或索引中筛选数据时使用,尤其是在扫描或查找之后进行筛选时。
  • 优化策略:

    • 索引列: 确保筛选条件中使用的列已编制索引。
    • SARGability (搜索参数能力): 确保 WHERE 子句的编写方式可以利用索引。例如,避免对 WHERE 子句中的列执行函数或操作(例如,‘WHERE YEAR(date_column) = 2020’),因为它们会阻止索引使用。
    • 避免使用复杂过滤器: 重写复杂过滤器或将其分解为更简单的过滤器可以提高性能。

3.JOIN 子句

  • 对应的执行计划步骤:

    • 嵌套循环连接: 一种简单高效的连接类型,适用于较小的结果集或连接键上有可用的索引。
    • 哈希联接: 在没有合适的索引或 SQL Server 决定为联接构建哈希表更有效时使用。
    • 合并联接: 通常在数据已经排序时使用,并且 SQL Server 可以有效地合并两个表的结果。
  • 优化策略:

    • Join Columns 索引: 确保用于连接的列上存在索引,这样可以提高性能,尤其是对于 嵌套循环连接
    • 考虑联接类型: 有时,手动强制使用特定的联接类型(使用像 ‘OPTION (HASH JOIN)’ 这样的查询提示)可以带来更好的性能。
    • 减少联接中的数据: 在执行联接之前,尽早使用筛选器(例如在子查询或 CTE 中)以减小数据集的大小。

4.GROUP BY 子句

  • 对应的执行计划步骤:

    • 聚合算子: 该算子用于对数据进行分组和计算聚合函数(如 COUNT、SUM、AVG)。
    • SQL Server 可能使用 SortHash Match 运算符对数据进行分组。
  • 优化策略:

    • 索引聚合: 创建可优化分组和聚合过程的索引,尤其是对于频繁查询的分组列。
    • 避免不必要的分组: 仅对您需要的数据进行分组。如果不需要按所有列分组,请减少列数。
    • 使用高效聚合: 对于大型数据集,请确保使用索引执行聚合,或将其分解为较小的块。

5.ORDER BY 子句

  • 对应的执行计划步骤:**

    • 排序运算符: 如果 SQL Server 无法使用现有索引来满足 ORDER BY 子句,它将使用 Sort 操作,这对于大型结果集来说可能很昂贵。
  • 优化策略:

    • ORDER BY 列的索引: 如果您的查询经常需要按特定列排序,请考虑创建包含这些列的索引。
    • 限制结果: 避免不必要地对大型数据集进行排序。如果使用分页,请考虑在排序之前添加 ‘TOP’ 子句来限制结果集。
    • 考虑批处理: 对于非常大的结果集,您可以分批处理数据。

6.SELECT 子句

  • 对应的执行计划步骤:

    • Projection Operator: SELECT 语句确定查询投影或返回哪些列。这在执行计划中通过 Projection 操作反映出来。
  • 优化策略:

    • 限制 SELECT 中的列: 只选择您需要的列,以避免不必要的 I/O。除非绝对必要,否则避免使用 ‘SELECT *’。
    • 消除冗余列: 确保您没有多次选择同一列或选择不必要的列。

7.HAVING 子句

  • 对应的执行计划步骤:

    • 过滤器运算符: 聚合数据(来自 GROUP BY 子句)后,应用 HAVING 子句以进一步过滤结果。这由执行计划中的 Filter 运算符反映。
  • 优化策略:

    • 使用 WHERE 而不是 HAVING: 如果可能,请在聚合之前在 WHERE 子句中应用条件,因为它会更高效(过滤器在执行过程的早期发生)。
    • 避免复杂条件: 简化复杂条件以提高性能。

8.子查询和派生表

  • 对应的执行计划步骤:

    • 计算标量: SQL Server 可能会创建一个 计算标量 操作来计算标量表达式(例如子查询)。
    • 嵌套循环或哈希匹配: SQL Server 可以具体化子查询,并使用不同的联接算法将它们与外部查询联接。
  • 优化策略:

    • 避免子查询: 尽可能将子查询替换为 JOINCTEs(公用表表达式),以提高可读性和性能。
    • 使用 EXISTS 而不是 IN: 对于检查是否存在的子查询,“EXISTS”往往比“IN”更有效,尤其是对于大型数据集。

9.临时表 / 表变量

  • 对应的执行计划步骤:

    • 插入/表扫描: 如果您使用临时表或表变量,SQL Server 将需要在查询执行期间扫描数据或将数据插入其中。
  • 优化策略:

    • 小型数据集的表变量: 在处理适合内存的较小数据集时,请使用表变量。
    • 适用于较大数据集的临时表: 如果数据较大,请使用临时表,并确保对它们进行适当的索引。
    • 避免过度使用临时表: 仅在必要时依赖临时表,因为它们会因磁盘 I/O 和表创建而带来开销。

10.排序和 DISTINCT

  • 对应的执行计划步骤:

    • **排序或哈希匹配:**如果涉及排序或重复数据删除(通过“DISTINCT”),SQL Server 可能会使用 Sort 运算符或 Hash Match 操作来执行这些操作。
  • 优化策略:

    • 限制结果: 除非必要,否则请避免在大型结果集中使用 ‘DISTINCT’。尝试在查询中更早地筛选数据。
    • 优化排序: 为用于排序的列编制索引,并确保结果集在应用排序之前尽可能小。

一般优化提示:

  • 统计信息: 确保统计信息是最新的,因为 SQL Server 依赖统计信息来生成最佳执行计划。
  • 查询提示:有时,SQL Server 的查询优化器可能会选择次优计划。‘OPTION (FORCESEEK)’ 或 ‘OPTION (LOOP JOIN)’ 等查询提示可用于影响优化器的选择。
  • 并行度: 如果查询足够复杂,SQL Server 可能会使用并行处理。您可以使用 ‘MAXDOP’ 提示来监控并行执行,以限制或强制并行性。

http://www.kler.cn/a/511136.html

相关文章:

  • 将IDLE里面python环境pyqt5配置的vscode
  • vue+高德API搭建前端3D交通页面
  • 二、点灯基础实验
  • ASP.NET Core中 JWT 实现无感刷新Token
  • C语言编程笔记:文件处理的艺术
  • LLM大语言模型的分类
  • md中的特殊占位文件路径的替换
  • Qt开发技术【C++ 实现类的二进制序列化与反序列化】
  • 使用vcpkg安装c++库时出现git网络连接报错的解决方案
  • LeetCode:46.全排列
  • doris:Kafka 导入数据
  • 异地IP属地代理业务解析:如何改变IP属地
  • 日志技术-LogBack入门程序Log配置文件日志级别
  • 满足不同场景的需求的智慧物流开源了
  • 和鲸科技受邀出席 2024(第四届)“风电领跑者”技术创新论坛
  • @Bean 控制 Spring Bean 生命周期
  • JavaScript语言的正则表达式
  • VSCODE SSH远程连接报错或无法联网安装.vscode-server
  • 深度学习篇---数据集分类
  • 【Unity3D】利用Hinge Joint 2D组件制作绳索效果
  • “深入浅出”系列之数通篇:(3)负载均衡
  • 【Linux】进程间通信IPC
  • 1.19学习记录
  • Amazon MSK 开启 Public 访问 SASL 配置的方法
  • 如何将自己本地项目开源到github上?
  • 2.6 聚焦:Word Embedding