SQL Server 执行计划(8) - 使用 SQL 执行计划进行查询性能调优

sqlserver 执行计划 一个很好的手册分享,执行计划里的属性解释官方文档:https://docs.microsoft.com/zh-cn/sql/relational-databases/showplan-logical-and-physical-operators-reference?view=sql-server-2017 想复杂的事情简单说,在看执行计划的其他文章的时候,发现直接上很复杂的DDL脚本来讲解,这样... 阅读详情

在本系列的前几篇文章(见底部索引)中,我们介绍了SQL 执行计划的多个方面,我们讨论了执行计划是如何在内部生成的,不同类型的计划,主要组件和运算符以及如何阅读和分析使用不同工具生成的计划。在本文中,我们将介绍如何使用执行计划来调整 T-SQL 查询的性能。

SQL Server 查询性能调优被认为是数据库管理员的首要任务,也是一场无休止的战斗,以使其托管系统获得最佳性能,同时消耗最少的资源。任何数据库管理员在考虑查询性能调优时都会想起的第一种方法就是使用 SQL 执行计划。这是因为SQL 执行计划可以指导我们如何去优化查询。SQL 执行计划中清晰显示了查询在内部执行的方式,执行路线图、以及整体查询中执行成本最高的部分、同时还提供了如何设计最佳索引的提示信息。

SQL 执行计划中存在许多通用迹象表明查询中可能存在性能不佳的地方。例如,在执行计划中成本最高的运算符,是排除查询性能故障的良好起点。此外,如果执行计划中出现了一个粗箭头后面跟随着一个细箭头的状况,表示在此处大量数据被处理,同时从一个运算符流向另一个运算符,而最终结果只是返回少量记录。这通常表明查询关联数据表中缺乏合适索引或存在数据乘法性能问题。

了解了本系列中讨论的每个运算符的作用后,你可以识别出不必要的额外的运算符,这些运算符会增加开销而降低查询性能。此外,如果存在扫描整个表或索引的 扫描(Scan) 运算符,在大多数情况下都表明缺少索引、索引使用不当或查询不包含过滤条件。查询性能问题的另一个信号是执行计划警告。这些消息提示了需要解决多种性能问题,例如 TempDb 溢出问题、缺少索引或错误的基数估计等。

我们通过以下示例来深入解如何使用 SQL 执行计划来调整 SQL 查询的性能。首先,我们将使用下面的 CREATE TABLE T-SQL 语句创建两个新表:

CREATE TABLE Employee_Main
( Emp_ID INT IDENTITY (1,1) PRIMARY KEY,
  EMP_FirsrName VARCHAR (50),
  EMP_LastName VARCHAR (50),
  EMP_BirthDate DATETIME,
  EMP_PhoneNumber VARCHAR (50),
  EMP_Address VARCHAR (MAX)  
)
GO
CREATE TABLE EMP_Salaries
( EMP_ID INT IDENTITY (1,1),
  EMP_HireDate DATETIME,
  EMP_Salary INT,
  CONSTRAINT FK_EMP_Salaries_Employee_Main FOREIGN KEY (EMP_ID)     
  REFERENCES Employee_Main (EMP_ID),
)
GO

创建表后,我们给每个表填充10 万条记录。

简单查询的调优

现在测试用的数据表格准备好了。假设我们需要改善以下SELECT 语句的性能:

SELECT [EMP_ID]
      ,[EMP_HireDate]
      ,[EMP_Salary]
  FROM [AdventureWorks2016CTP3].[dbo].[EMP_Salaries]
  WHERE [EMP_ID]< 1000

调整查询性能的最佳方法是研究该查询的 SQL 执行计划。上面的 SELECT 查询的实际执行计划如下图所示:
简单查询调优-调优前

从生成的计划中可以清楚地看出,SQL Server 引擎扫描了所有表行(10 万条记录)以检索请求的数据(1 条记录)。从执行计划中我们可以看到3个明显存在问题的地方:

  1. 表扫描(Table Scan)运算符
  2. 表扫描(Table Scan)运算符的高执行成本
  3. 从粗箭头(将数据从表扫描操作输出到到下一个操作符)到细箭头(结果的输出)转换。

从上面执行计划中的三个问题迹象将我们可以得知性能不佳的主要原因是EMP_Salary 表中缺少索引。接下来我们通过 以下CREATE INDEX T-SQL 语句在 EMP_Salary 表的 EMP_ID 列上创建索引:

CREATE NONCLUSTERED INDEX IX_EMP_Salaries_EMP_ID ON EMP_Salaries (EMP_ID)

然后运行相同的 T-SQL 语句。从新的执行计划中可以看出,SQL Server 引擎将直接在新创建的索引中查找请求的数据,无需扫描整个底层表,索引查找处理的成本降低到了50%。另外,从Index Seek操作符流到下一个操作符流的记录数明显减少,从箭头粗细就可以看出。详细执行计划如下图所示:
![简单查询调优-调优后
再看看查看查询的执行统计信息,可以看到看到行数减少到 2,而持续时间和 CPU 成本可以忽略不计。详细信息如下图所示:
在这里插入图片描述

我们在深入看看执行计划。我们还能发现另一个性能问题的迹象,那就是额外昂贵的 RID Lookup 和 Nested Loops 运算符。回想一下上一篇关于执行计划运算符的文章,我们可以通过创建覆盖索引来解决再次检索基础表的问题。

我们接着使用下面的 CREATE INDEX T-SQL 语句,为该查询创建覆盖索引:

CREATE NONCLUSTERED INDEX IX_EMP_Salaries_EMP_ID ON EMP_Salaries (EMP_ID) INCLUDE (EMP_HireDate,EMP_Salary ) WITH DROP_EXISTING

再次运行相同的SELECT语句。在最新的执行计划中,RID Lookup和Nested Loops操作符不再出现,因为SQL Server 引擎在索引中已经找到了所有请求的数据。详细执行计划如下图所示:
简单查询调优2-调优后

复杂查询调优

结下来,我们再看一个复杂查询的调优示例。
让我们先删除在之前在 EMP_Salaries 表上创建的索引。使用下面的 DROP INDEX T-SQL 语句:

DROP INDEX IX_EMP_Salaries_EMP_ID ON EMP_Salaries

假设我们需要调整以下 SELECT 查询的性能,该查询连接先前创建的两个 EMP 测试表,以检索员工的信息:

SELECT EMP_FirsrName, EMP_LastName, EMP_BirthDate, EMP_Address, EMP_HireDate, EMP_Salary
FROM [dbo].[Employee_Main] EM
JOIN  [dbo].[EMP_Salaries] ES
ON EM.[EMP_ID] =ES.[EMP_ID]
WHERE EM.[EMP_ID] > 2470 AND ES.EMP_Salary >450

执行 SELECT 查询,从生成的实际计划中我们可以看到多个性能问题的迹象,例如 表扫描(Table Scan) 运算符-扫描了整个底层表。粗箭头-大量数据在操作符之间流转。不必要的昂贵运算符-例如Hash Match 运算符。详细的SQL 执行计划如下图所示:
复杂查询调优-优化前
进一步查看查询的执行统计话剧,会发现读取量大,持续时间长,CPU开销高等问题。详细如下图所示:
在这里插入图片描述

在执行计划的上半部分,我们看到SQLServer提示了的需要创建的推荐索引(绿色文字)。创建推荐索引可以提升查询的性能。我们通过以下T-SQL创建推荐索引:

复杂查询调优-创建索引

创建索引后,再次执行 SELECT 语句。在最新的执行计划中我们可以看到 表扫描(Table Scan) 运算符更改为了 索引查找(Index Seek) 操作符。但是箭头仍然保持为粗箭头,这是这里的正常行为,因为没有从粗箭头到细箭头的过渡。详细执行计划如下图所示:
在这里插入图片描述

我们在看一下执行计划的统计数据。执行时长和CPU消耗都得到了少量改善。
在这里插入图片描述

下一步我们可以通过,改善查询语句来实现查询性能的增强。例如,可以使用限制返回行数的 TOP 子句来减小箭头的粗细。另一方面,可以通过使用下面的 CREATE INDEX T-SQL 语句在 EMP_Salaries 表上创建新索引来避免Filter 运算符的使用:

CREATE NONCLUSTERED INDEX [IX_EMP_Salaries_EMP_Salary] ON [dbo].[EMP_Salaries]  ([EMP_Salary] )

优化后生成的最新执行计划如下图所示:
复杂查询调优-最终优化结果

从以上的示例可以清楚地看出,SQL 执行计划在调整不同 T-SQL 查询的性能方面的重要作用。请继续关注下一篇文章,我们将介绍执行计划在 SQL Server 内存中的保存位置以及如何保存执行计划以供重用!

系列目录

SQL Server 执行计划(1) - 概述
SQL Server 执行计划(2) - 执行计划类型
SQL Server 执行计划(3) - 如何分析图形执行计划
SQL Server 执行计划(4) - 执行计划运算符详解1
SQL Server 执行计划(5) - 执行计划运算符详解2
SQL Server 执行计划(6) - 执行计划运算符详解3
SQL Server 执行计划(7) - 执行计划运算符详解4
[SQL Server 执行计划(8) - 使用执行计划进行查询性能调优]
[SQL Server 执行计划(9) - 保存和比较执行计划]

Microsoft Sql Server 2019 执行计划 用户提交的 sql 语句,数据库查询化器,经过分析生成多个数据库可以识别的高效执行查询方式。然 后化器会在众多执行计划中找出一个资源使用最少,而不是最快的执行方案,给你展示出来,可以是 文本格式,也可以是图形化的执行方案。 阅读详情

相关推荐

数据库性能技术系列文章(2)--深入理解单表执行计划

  数据库性能技术系列文章(2)                            --深入理解单表执行计划                               作者:杨万富 一、概述      这篇文章是数据库性能技术的第二篇。上一篇讲解的索引数据库性能技术的基础。这篇讲解的深入理解单表执行计划,是数据库性能的有力工具。     

ywf的专栏 3455

SQL Server查询执行计划–查看计划

In the SQL Server query execution plans – Basics, we described the query execution plans in SQL Server and why they are important for performance analysis. In this article, we will focus on the method...

culuo4781的博客 4345

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

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

weixin_30777913的博客 1001

SQL Server执行计划(Execution Plans)

为了能够执行查询SQL Server 数据库引擎必须分析该语句,以确定访问所需数据的最有效方法。此分析由称为查询化器的组件处理。查询化器的输入由查询数据库架构(表和索引定义)和数据库统计信息组成。查询化器的输出是查询执行计划,有时称为查询计划执行计划

Lion_Long的博客 5419

SQL执行计划

打开了以下的某些配置,再通过打开即可,返回SQL语句的执行信息,但不执行SQL语句。

weixin_55797790的博客 1288

SQLServer性能化分析--执行计划、耗时SQL排查和死锁处理

SQLServer性能分析--执行计划、耗时SQL排查和死锁处理

sinat_41883985的博客 1859

SQL化 之 执行计划分析(sql server 数据库

执行计划SQL Server查询化器生成的指令集,描述了如何执行查询。通过分析执行计划,可以识别性能瓶颈并进行化。

u013334925的博客 1281

掌握SQL语句执行计划性能化与查询分析

本文还有配套的精品资源,点击获取 简介:在数据库性能化中,执行计划是关键,它展示了SQL语句的处理细节,如数据检索、表扫描顺序、索引使用等。本文深入探讨如何获取和分析执行计划,以查询性能,涵盖执行计划的重要性、获取方法、关键元素,以及常见SQL语句的执行计划分析和整策略。 1. SQL执行计划的重要性 在数据库性能的舞台上,SQL执行计划是一个关...

weixin_42471823的博客 1649

SQL Server 2017查询性能指南

SQL Server查询化器是数据库管理系统中至关重要的组件之一。它的核心作用是对用户的SQL查询语句进行分析,选择出最高效的查询执行计划。这个过程极大地依赖于数据表内的统计信息和系统提供的资源信息,其目的是减少查询所消耗的资源,提高查询的响应速度和处理能力。查询化器的化结果直接影响到数据库性能表现,因此,深入了解查询化器的运作机制对于数据库管理员和开发者来说具有重要价值。存储引擎的选择对数据库性能至关重要,尤其是在事务处理和并发控制方面。

weixin_34438187的博客 686

深入浅出SQL Server 2005性能指南

SQL Server 2005作为一个成熟的关系数据库管理系统,其性能对于确保企业级应用的稳定性和响应速度至关重要。性能不仅可以提升现有数据库的效率,还能在资源有限的情况下最大化其处理能力。

weixin_32661831的博客 879

SQL Server执行计划(2) - 如何查看执行计划

在上一篇文章中,我们详细描述了提交的 SQL Server 查询所经历的不同阶段以及 SQL Server 关系引擎如何处理它。SQL Server 关系引擎生成执行计划SQL Server 存储引擎执行请求的数据检索或修改过程。在本文中,我们将讨论 SQL Server 执行计划的不同类型和格式。 执行计划类型 SQL Server 执行计划是已提交查询执行路线图的图形表示,SQL Server 查询化器将遵循该路线图。SQL Server 为我们提供了两种主要类型的执行计划。 预估执行计划 :

信天翁的博客 1万+

SQL Server查询计划(Query Plan)(6)——图形查询计划

本文对SQL Server查询计划(Query Plan)——图形查询计划的概念、使用方法、使用步骤及相关指标理解等,进行了较为深入详细的说明和讲解,并对注意事项、关键知识点和选项等进行了重点标注和详尽解析,以便于读者进行深入学习和理解。

数据库生态圈(RDB & NoSQL & Bigdata)——专注于关系库应用与研究(Oracle & Mysql & Postgresql & SQL Server ) 2023

SQL Server性能化实战:从瓶颈定位到高效

SQL Server性能化需结合监控数据、索引策略与代码,持续跟踪改进效果。建议定期进行健康检查,并在测试环境验证变更。

xiaoyu❅的博客 2306

如何在SQL Server 2016中比较查询执行计划

SQL Server 2016 provides great enhancement capability features for troubleshooting purposes. Some of the important features are: SQL Server 2016提供了强大的增强功能,可用于故障排除。 一些重要的功能是: Query store ...

culuo4781的博客 525

如何查看SQL server 执行计划

<br />欢迎转载。转载请保留原作者姓名以及原文地址,并请注明译文出处:http://blog.csdn.net/xiao_hn<br /> <br /> <br />当需要分析某个查询的效能时,最好的方式之一查看这个查询执行计划执行计划描述SQL Server查询化器如何实际运行(或者将会如何运行)一个特定的查询。<br /> <br />查看查询执行计划有几种不同的方式。它们包括:<br /> <br />SQL Server查询分析器里有一个叫做”显示实际执行计划”的选项(位于”查询”下拉菜

Sky_666的专栏 3275

SQL Server查询过程、执行计划学习总结

SQL Server查询过程、执行计划 Building Blocks的概念 SQL Server的每一个查询都是由Building Block组成的集合,Building Block分为两种,operators和iterators。一个iterator从它的子iterator中获取数据,经过处理后返回给它的父iterator。 所有iterator都实现了一个接口, 这个接口中有两个函数,O...

qq_35170267的博客 1044

SQL Server 2016里使用查询存储进行性能

作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题。 我就多次听到,以前的SQL Server性能问题都还好且在正常范围内,但现在一切已经改变,SQL Server开始糟糕, 疯狂的事情不能解释。在这个情况下我介入,分析下整个SQL Server的安装,最后用一些神奇的查方法找出性能问题的根源。 但很多时候问题的根源是一样...

静宁宇思 936

AI Agent项目落地实战:从原理到工程化的关键挑战与解决方案

AI Agent(智能体)作为当前人工智能领域的热点技术,其核心是基于大语言模型(LLM)的感知-决策-执行循环,通过用工具集来自动化处理特定任务。这项技术的价值在于将强大的语言理解能力与可编程的操作接口相结合,从而在自动化客服、智能文档处理、流程触发等场景中释放生产力。然而,其实践应用常面临四大关键挑战:问题定义模糊导致任务超出Agent能力边界;工具生态脆弱,API不稳定或返回非结构化数据影响可靠性;提示词设计不佳,无法有效引导Agent行为;以及缺乏系统化的评估、监控与迭代机制。要构建鲁棒的Agen

weixin_33730836的博客 356
上一篇: SQL Server 执行计划(7) - 执行计划运算符详解4
下一篇: SQL Server 执行计划(9) - 保存和比较执行计划
albatross76
博客等级 码龄19年 16粉丝 2原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值