SQL调优指南笔记3:SQL Processing

Posted dingdingfish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL调优指南笔记3:SQL Processing相关的知识,希望对你有一定的参考价值。

本文为SQL Tuning Guide第3章“SQL 处理”的笔记。

3.1 About SQL Processing

SQL 处理是对 SQL 语句的解析、优化、行源生成和执行。如下图:

3.1.1 SQL Parsing

SQL解析是SQL执行的第一阶段。解析阶段涉及将 SQL 语句的各个部分分离成其他例程可以处理的数据结构。 数据库在应用程序指示时解析语句,这意味着只有应用程序而不是数据库本身可以减少解析次数。

当应用程序发出 SQL 语句时,该应用程序请求数据库解析调用parse call)以准备要执行的语句。 解析调用会打开或创建一个游标,它是会话特定私有 SQL 区域(private SQL area,内存中的一个区域,用于保存已解析的语句和其他要处理的信息)的句柄,该区域包含已解析的 SQL 语句和其他处理信息。 游标和私有 SQL 区位于程序全局区 (PGA) 中。

解析的过程包括语法检查、语义检查和共享池检查。

语法检查是指是否符合SQL语法。语义检查确定语句是否有意义,如表名列名是否存在。共享池检查确定是否可以跳过语句处理中资源密集型步骤。

为此,数据库使用哈希算法为每个 SQL 语句生成一个哈希值。 语句哈希值即 V$SQL.SQL_ID 中显示的 SQL ID。 该哈希值在 同一Oracle 数据库版本中是确定的,因此单个或不同实例中的相同语句具有相同的 SQL ID。

当用户提交一条 SQL 语句时,数据库会在共享 SQL 区域中查找现有的已解析语句是否具有相同的哈希值。如果找到具有相同哈希值的已解析语句,则为软解析,已有的代码可以重用,可以省略后续优化、行源生成过程;否则为硬解析,DDL语句总是执行硬解析。软解析和硬解析分别称为library cache hit和library cache miss。

如果检查确定共享池中的语句具有相同的哈希值,则数据库执行语义和环境检查以确定语句是否具有相同的含义。语法相同是不够的,例如对于以下SQL,不同的用户下可能有自己的my_table:

SELECT * FROM my_table;

即使语法和含义完全,环境的不同也可能导致仍需要硬解析,如影响执行计划生成的会话设置。

3.1.2 SQL Optimization

在优化期间,Oracle 数据库必须对每个唯一的 DML 语句至少执行一次硬解析,并在此解析期间执行优化。DDL语句无需优化。

3.1.3 SQL Row Source Generation

行源生成器是一种软件,它从优化器接收最佳执行计划并生成可供数据库其余部分使用的迭代执行计划

行源是由执行计划中的步骤返回的行集以及可以迭代处理行的控制结构。 行源可以是表、视图或联接或分组操作的结果。

行源生成器生成行源树row source tree),它是行源的集合。SQL 语句的行源树显示了诸如表顺序、访问方法、连接方法和数据操作(例如过滤、排序)之类的信息。行源树是执行计划中最主要的部分。

3.1.4 SQL Execution

在执行期间,SQL 引擎执行行源生成器生成的树中的每个行源。 此步骤是 DML 处理中唯一的强制性步骤(也就是说解析也是可选的?)。

下图称为执行树或解析树,一般来说,执行中步骤的顺序与计划中的顺序相反,因此您从下往上阅读计划。

此图对应的执行计划如下,每一行都有Id,Operation列中的空格表示继承关系:

---------------------------------------------------------------------------
| Id| Operation                    | Name      |Rows|Bytes|Cost(%CPU)|Time|
---------------------------------------------------------------------------
| 0| SELECT STATEMENT              |             | 3 |189 |7(15)|00:00:01 |
|*1|  HASH JOIN                    |             | 3 |189 |7(15)|00:00:01 |
|*2|   HASH JOIN                   |             | 3 |141 |5(20)|00:00:01 |
| 3|    TABLE ACCESS BY INDEX ROWID| EMPLOYEES   | 3 | 60 |2 (0)|00:00:01 |
|*4|     INDEX RANGE SCAN          | EMP_NAME_IX | 3 |    |1 (0)|00:00:01 |
| 5|    TABLE ACCESS FULL          | JOBS        |19 |513 |2 (0)|00:00:01 |
| 6|   TABLE ACCESS FULL           | DEPARTMENTS |27 |432 |2 (0)|00:00:01 |
---------------------------------------------------------------------------

图中的每一个节点表示一个行源,即执行计划中的一个步骤。黑框指示的步骤从数据库中的对象物理检索数据。 这些步骤即访问路径(access path),指用于从数据库检索数据的技术,如全表扫描或索引。白框指示的步骤对行源进行操作,如哈希联结。

在某些执行计划中,步骤是迭代的,而在其他执行计划中,步骤是顺序的(如哈希联结)。

在执行过程中,如果数据不在内存中,则数据库将数据从磁盘读取到内存中。 数据库还生成确保数据完整性所需的任何锁和闩锁,并记录在 SQL 执行期间所做的任何更改。 处理 SQL 语句的最后阶段是关闭游标。

3.2 How Oracle Database Processes DML

大多数 DML 语句都有一个查询组件。 在查询中,游标的执行将查询结果放入称为结果集的一组行中。

3.2.1 How Row Sets Are Fetched

结果集行可以一次提取一行或成组提取。

在提取阶段,如果查询请求,会对行进行排序。 每次连续提取都会检索另一行结果,直到提取到最后一行。

通常,在获取最后一行之前,数据库无法确定某个查询要检索的行数。 Oracle 数据库检索数据以响应 fetch 调用,因此数据库读取的行越多,它执行的工作就越多。 对于某些查询,数据库尽快地返回第一行,而对于其他查询,它创建整个结果集后再返回第一行。

3.2.2 Read Consistency

一般情况下,查询使用Oracle数据库读取一致性机制来检索数据,该机制保证查询读取的所有数据块在单个时间点上是一致的。读取一致性使用undo数据来显示数据的历史版本。

3.2.3 Data Changes

更改数据的 DML 语句使用读取一致性仅检索在修改开始时与搜索条件匹配的数据。

之后,这些语句检索当前状态中存在的数据块并进行所需修改。 数据库必须执行与数据修改相关的其他操作,例如生成redo和undo数据。

3.3 How Oracle Database Processes DDL

Oracle 数据库处理 DDL 的方式与 DML 不同。因为DDL是在数据字典中定义对象的一种方式。 通常,Oracle 数据库必须解析和执行许多递归 SQL 语句才能执行 DDL 语句。

以上是关于SQL调优指南笔记3:SQL Processing的主要内容,如果未能解决你的问题,请参考以下文章

SQL调优指南笔记9:Joins

SQL调优指南笔记9:Joins

SQL调优指南笔记6:Explaining and Displaying Execution Plans

SQL调优指南笔记2:SQL Performance Methodology

SQL调优指南笔记11:Histograms

SQL调优指南笔记11:Histograms