SQL性能第2篇:查询分析和访问路径制定

女主宣言

在SQL性能概述的第一部分中,我们研究了关系优化及其影响因素。在今天的文章中,我们将注意力转向查询分析以及SQL转换为可执行代码的方式。

从上层看,优化过程包括四个步骤:

  1. 接收并验证SQL语句。

  2. 分析环境,优化满足SQL语句的方法。

  3. 创建机器可读的指令来执行优化的SQL。

  4. 执行这些指令或将它们存储起来以备将来执行。

需要做的第一件事是验证SQL是否写对了。这并不意味着它会做你希望它做的事情,只是它符合所需的语法。将对SQL进行分析和检查。如果遇到任何错误,进程将停止,你必须修改SQL,直到它正确为止。在验证SQL语法之后,下一步是检查语义,例如数据类型、引用约束、检查约束、视图和触发器。

这个过程的第二步是最有趣的。优化器如何决定如何执行可以按其方式发送的大量SQL语句?此查询分析步骤扫描SQL以确定其总体复杂性。SQL语句的表达式是决定优化器选择的访问路径的一个重要因素。查询的复杂性、谓词的数量和类型、函数的存在以及排序子句的存在都将进入优化器计算的估计成本中。

SQL语句越复杂,查询分析就必须做越多的工作来理解SQL语句。在查询分析期间,优化器分析SQL语句和数据库系统的各个方面,例如

  • 需要哪些数据库中的哪些表

  • 是否需要将任何视图分解为基础表

  • 是否需要表连接或子选择

  • 是否需要UNION、EXCEPT或INTERSECT

  • 可以使用哪些索引(如果有的话)

  • 必须满足多少谓词(WHERE子句)

  • 必须执行哪些函数

  • SQL是否使用OR或AND

  • DBMS如何处理SQL语句的每个组件

  • 为SQL语句中的表使用的数据缓存分配了多少内存

  • 如果查询需要排序,有多少内存可用于排序

换句话说,查询分析将SQL语句分解为必须执行的离散任务,以返回查询结果。

现代关系优化器是基于成本的,这意味着优化过程总是试图为每个查询制定一个降低总体成本的访问路径。为了实现这一点,优化器应用查询成本公式来评估和权衡每个潜在访问路径的多个因素:这些因素包括CPU成本、I/O操作、系统编目中的统计信息以及实际的SQL语句代码。

优化器可以重写查询,将其转换为等效的、但更容易编译和优化的版本。谓词下推和转换可能在此时发生。然后优化SQL。将审查和分析多条访问路径,以选择成本最低的选项。最后一步是创建实际的可执行代码。

1

关系优化器有许多创建SQL访问路径的选项。在较高的层次上,有访问单个表中的数据的方法,也有组合两个表中的数据的方法。可以将这些方法组合成一系列访问方法,为SQL语句创建总体访问路径。

对于单表访问,可以使用扫描或索引检索数据。在优化器确定每个谓词可用的索引之后,它将决定是使用单个索引、多个索引还是根本不使用索引。

大家很容易说索引访问将优于扫描访问,但事实并非总是如此。优化器必须评估必须访问的数据量以及查询的性质。例如,如果你正在创建一个包含表中每一行的报告,那么使用索引可能比使用扫描读取所有数据要慢。

表扫描是最简单的数据访问形式。表扫描是通过读取表的每一行来执行的。根据DBMS的不同,可能存在另一种扫描类型,称为表空间扫描。表空间扫描读取表空间中的每个页面,表空间可能包含多个表。显然,表空间扫描将比表扫描运行得慢,因为可能会产生额外的I/O读取不适用的数据。

另一种扫描形式是分区扫描。如果DBMS能够确定要访问的数据存在于多分区表(或表空间)的某些分区中,那么它可以将扫描到的数据限制到适当的分区。分区扫描应该优于表扫描或表空间扫描,因为所需的I/O数量减少了。

通常,优化器会选择扫描数据,原因如下之一: