Oracle查询优化器(一)

本系列文章将会介绍Oracle数据库中核心组件之一的查询优化器,并尝试从SQL执行的角度来介绍查询优化器的基础概念、组成以及工作原理。

SQL

众所周知,SQL是一种结构化的查询语言。我们在使用SQL编写查询语句的时候,并不会指定从数据库中查询数据的方式,而是会用直观的方式列出数据的查询需求。以下述SQL语句为例:

select age from student where sno = 1;

SQL语句列出查询需求:从student表中查询学号为1的学生的年龄。作为SQL的编写人员,并不需要知道数据库内部的工作原理,只需要列出这样的一种查询需求,数据库内部的诸多组件就会互相协同,按照规范化的步骤从数据库中查询出结果。

查询优化器的概念

在Oracle数据库的诸多组件中,查询优化器(以下简称优化器)的职责是为SQL语句生成执行计划。基于SQL结构化语言的特点,优化器在为特定SQL生成执行计划的时候会面临如下常见问题:
1)从SQL中涉及到的每一个表查询数据的最优访问路径是什么?
2)SQL中涉及到的多个表以哪种连接方式、和连接顺序进行连接最高效?
3)在SQL语句执行期间,什么时候应该处理聚合和/或排序?

在实际情况中,优化器并不会直接回答这些问题。优化器会搜索所谓的search space(其中包含所有潜在的执行计划)以追求最优的执行计划。为了确定哪个执行计划是最优的,优化器会评估执行计划的成本,并选择成本最低的一个。这种类型的优化器被称作基于成本的优化器,即CBO。从Oracle 10g起RBO(基于规则的查询优化器)不再被Oracle支持,因此我们在此不再介绍RBO。

Branch-and-Bound

我们知道,优化器需要在有限的时间内找到代价最小的执行计划。因此可以理解,对于优化器而言,它并不会经常搜索一个SQL语句的所有可能的执行计划(可能会耗费大量时间)。优化器通过所谓启发式的方法来搜索所有可能执行计划的一个子集。具体来说,优化器通过branch-and-bound算法来评估最有希望的执行计划,然后考虑不同的执行计划,直到找到代价最低的执行计划或探测到过多的执行计划为止。

Branch-and-bound算法中,branch指代可选的执行计划分支(如,一个访问路径或一个连接方法),而bound指代优化器搜索最优执行计划过程中找到的迄今为止最佳执行计划的成本——一旦当前执行计划分支的成本高于bound,优化器就会直接丢弃该branch(可能还有branch下列的所有子branch)。通过采用这种算法,优化器可以做到在合理的时间范围内确定最高效的执行计划。

查询优化器的组成

查询优化器由三部分组成:查询转换器(Query Transformer)、成本估算器(Estimator)、计划生成器(Plan Generator)。图一展示了查询优化器中三个组成部分的关系。


图一 查询优化器.png
  • 查询转换器
    优化器通过在查询转换器中应用不同的查询转换技术生成新的语义上等价的SQL语句。这一阶段称又可称作逻辑优化。逻辑优化的目标是确定查询转换的最佳组合(或是否需要做查询转换)。优化器通过逻辑优化这一过程来明确更改查询的形式是否有助于其生成更好的执行计划,如果有那就更改,反之则保持原样。

  • 成本估算器
    在查询转换器处理之后,优化器会为每个SQL语句会生成若干个不同的执行计划。而后,每一个执行计划都会被传递给成本估算器,让它计算成本。最后,优化器选择成本最低的执行计划。这一阶段可称为物理优化。在物理优化的过程中,成本估算器需要根据数据字典中的统计信息来确定执行计划的代价。

  • 计划生成器
    经过查询转换器和成本估算器之后,优化器比较所有备选的执行计划并选择成本最低的计划传递给行源生成器。行源生成器从优化器接收到优化后的执行计划,然后为该计划生成行源(Row Source),并最终传递给执行引擎(只有经过行源生成器处理过的执行计划才能被执行引擎使用)。

本文简单介绍了查询优化器的概念以及搜索执行计划的核心算法Branch-and-Bound、查询优化器的组成部分等内容。在系列后续文章中,将会详细介绍查询优化器的各个组件的技术细节,敬请期待!

你可能感兴趣的:(Oracle查询优化器(一))