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 Scan 或 Clustered 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 可能使用 Sort 或 Hash 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 可以具体化子查询,并使用不同的联接算法将它们与外部查询联接。
-
优化策略:
- 避免子查询:尽可能将子查询替换为 JOIN 或 CTEs(公用表表达式),以提高可读性和性能。
- 使用 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’ 提示来监控并行执行,以限制或强制并行性。
原文地址:https://blog.csdn.net/weixin_30777913/article/details/145175576
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!