数据结构论坛

首页 » 分类 » 常识 » 关于SQL查询优化的详细指南,赶紧收藏
TUhjnbcbe - 2024/5/15 16:29:00

SQL(结构化查询语言)是一种用于访问、存储、创建、删除数据库以及执行所有其他与数据相关操作的标准语言。SQL中有四种类型的语言:

1.DDL(数据定义语言)

这包括用于创建和更改数据库架构的命令。例如,创建、删除、更改、删节。

2.DML(数据操作语言)

这包括用于更新数据库中数据的命令。例如,选择、更新、插入、删除。

3.DCL(数据控制语言)

这包括用于访问数据库的命令。例如,授予、撤销。

4.TCL(交易控制语言)

这包括用于管理数据库中事务的命令。例如,提交、恢复。

图片来源:谷歌图片

在进入SQL查询优化的主题之前,我们先来了解一下查询的实际处理过程:

一、查询处理

查询处理被定义为与从数据库中提取数据相关联的一组阶段。它包括将用高级语言(如SQL)编写的查询转换为可通过数据库的物理级别实现、SQL查询优化技术和查询的原始评估来理解的形式。

查询处理涉及三个主要步骤:

1.解析器和转换器:查询处理的第一步是解析和翻译。解析器就像编译器中的解析器一样,会检查查询的语法,无论数据库中是否存在上述关系。高级查询语言(如SQL)适合人们使用,但是,它完全不适合系统内部表示,因此需要翻译。内部表示可以是关系代数的扩展形式。

2.优化:SQL查询可以用许多不同的方式编写。优化后的查询还取决于数据在文件组织中的存储方式。查询还可以具有不同的对应关系代数表达式。

3.执行计划:从数据库获取数据的基本操作的系统分步执行称为查询评估计划。针对特定查询的不同评估计划具有不同的查询成本。成本可能包括磁盘访问次数、执行查询的CPU时间、分布式数据库的通信时间。

二、SQL查询优化的目的

SQL查询优化的主要目的是:

1.减少响应时间:主要目标是通过减少响应时间来提高性能。为了更好的用户体验,用户请求数据和获取响应之间的时间差应该最小化。

2.减少CPU执行时间:为了获得更快的结果,必须减少查询的CPU执行时间。

3.提高吞吐量:在特定查询中要获取的行数应该以最有效的方式进行,以便使用最少的资源。

注:

在本教程中,我们将使用AdventureWorks数据库来显示各种命令及其优化的解决方案。

AdventureWorks数据库是由MicrosoftSQLServer提供的示例数据库。这是一个标准数据库,用于显示企业的日常事务处理。场景包括销售、客户管理、产品管理和人力资源。

三、用于分析SQL查询性能的指标

在空间、时间、CPU利用率和其他资源方面,有几种计算查询成本的指标:

1.执行时间:分析查询性能最重要的指标是查询的执行时间。执行时间/查询持续时间是指查询从数据库返回行所花费的时间。我们可以使用以下命令查找查询持续时间:

通过使用STATISTICSTIMEON,我们可以看到查询的解析时间、编译时间、执行时间和完成时间。

解析和编译时间:解析和编译查询以检查查询语法所需的时间称为"解析"和"编译时间"。

执行时间:查询获取数据所用的CPU时间称为"执行时间"。

完成时间:查询返回结果的确切时间称为"完成时间"。

通过分析这些时间,我们可以清楚地了解查询的执行是否符合要求。

2.统计IO:

IO是在查询时访问内存缓冲区以进行读取操作所花费的主要时间。它提供了对执行查询的延迟和其他瓶颈的深入了解。通过设置STATISTICSIOON,我们可以获得执行查询而执行的物理和逻辑读取次数。

从SalesLT.Customer中选择*;

逻辑读取:从缓冲区缓存执行的读取次数。

物理读取:当在缓存中不可用时,从存储设备执行的读取次数。

3.执行计划:

执行计划是优化程序用于读取行的详细分步处理计划。可以使用以下过程在数据库中启用它。它能帮助我们分析查询执行的主要阶段。我们还可以找出执行的哪个部分需要更多时间,并优化该子部分。

正如我们在上面看到的,执行计划显示出访问了哪些表,执行了哪些索引扫描来获取数据。如果存在join,则显示这些表的合并方式。

此外,我们还可以看到在查询执行期间执行的每个子操作的更详细的分析视图。

如上图所示,我们可以得到读取的行数,实际批处理数、估计的操作员成本,估计的CPU成本、估计的执行次数、实际重新绑定的值。这为我们提供了查询执行中涉及的几种成本的详细概述。

四、SQL查询优化技术

1.索引Indexing

索引是一种数据结构,用于根据搜索键快速访问表。它有助于最大限度地减少从数据库中读取行的磁盘访问。索引操作可以是扫描或查找。索引扫描遍历整个索引以获取匹配条件,而索引查找则筛选匹配筛选器上的行。

例如:

在上面的查询中,我们可以看到有99%的查询执行时间都花在了索引查找操作上。因此,它是优化过程的重要组成部分。

索引选择准则:

1.索引应对WHERE子句和JOIN语句中经常出现的键进行索引。

2.不应在经常修改的列上建立索引,即经常对这些列应用UPDATE命令。

3.应在同时执行INSERT、UPDATE和DELETE的外键上建立索引。

4.应使用AND运算符对WHERE子句中通常一起出现的属性编制索引。

5.应在对键值进行排序时编制索引。

2.选择Selection

选择所需的行,而不是选择所有行。SELECT*在扫描整个数据库时效率是非常低的。

从上面的两个输出中可以看出,当我们使用SELECT语句仅选择所需的列时,时间会减少到四分之一。

避免使用SELECTDISTINCT

SQL中的SELECTDISTINCT命令用于获取唯一结果并删除关系中的重复行。为了完成这个任务,它基本上将相关的行组合在一起,然后将其删除。GROUPBY操作的成本比较高,因此,若要获取不同的行并删除重复的行,可以在SELECT操作中使用更多属性。

举个例子,

从上述两个查询的执行中可以看出,DISTINCT操作需要更多的时间来获取唯一行。因此,最好在SELECT查询中添加更多属性,以提高性能并获取唯一的行。

3.内连接VSWHERE子句

我们应该使用内连接来合并两个或多个表,而不是使用WHERE子句。

从上面的输出中可以看出,与使用WHERE子句进行连接相比,内部连接几乎需要一半的时间。

4.限制命令

limit命令用于控制结果集中要显示的行数。结果集只需要显示那些必需的行。因此,必须对生产数据集使用limit,并为生产目的提供按需的行计算。

上面的查询输出结果集的前10行。查询性能大大提高了。

5.IN与EXISTS

在扫描方面,IN运算符比EXISTS操作符的成本更高,尤其是当子查询的结果是大型数据集时。因此,我们应该尝试使用EXISTS,而不是使用IN来获取子查询的结果。

举个例子,

我们使用IN命令和EXISTS命令执行了相同的查询,并观察到与IN命令相比,EXISTS命令只花费了一半的时间,而且物理和逻辑扫描的数量非常少。

6.循环与批量导入/更新

必须避免这些循环,因为它需要多次运行相同的查询。相反,我们应该选择批量插入和更新。

正如上图所示,批量导入比循环语句工作得更快。

1
查看完整版本: 关于SQL查询优化的详细指南,赶紧收藏