识别次优访问路径 3

1.1.1      原因

造成低效访问路径的主要原因有以下几个。

Ø  没有使用适合的访问结构(比如索引)。

Ø  使用了适合的访问结构,但是SQL语句的语法不允许查询优化器使用它。

Ø  表或索引是分区的,但是无法修剪。结果,所有的分区都需要访问。

Ø  表和/或索引没有适当的分区。

除了之前列表中的例子之外,还有另外两种情况会导致低效访问路径。

Ø  查询优化器做出错误判断时,可能是由于缺少对象统计信息,或是由于对象统计信息过旧,或由于使用了错误的查询优化器配置。这些没有放在上面的列表中,是因为默认对象统计信息必须是最近的并且查询优化器也是配置正确的。

Ø  当查询优化器自身出现问题时,比如,当出现内部bug或底层限制时。

1.1.2      解决方案

正如上一部分描述的那样,要高效执行SQL语句,目标就是最小化逻辑读,或者换句话说,使用访问路径访问更少的块。要达到这个目标,或许需要增加新的访问结构(比如,索引)或者改变物理设计(比如,对表或者它们的索引进行分区)。给定的SQL语句,会有很多访问结构和物理设计的组合。幸运的是,为了使选择更容易,可以根据选择性将SQL语句(或者更容易些,数据访问操作)分成以下两大类别:

Ø  弱选择性操作

Ø  强选择性操作

选择性很重要,因为访问结构和设计对弱选择性操作支持较好,对强选择性操作支持较差,反之亦然。然而,请注意这两个类别并没有明确的界限。相反,它是依赖于操作的,依赖于它处理的数据和数据存储的方式。

例如,数据分布和每块存储行数严重影响着性能。换句话说,并没有这样绝对的说法:选择率小于0.1必定是强选择性,而超过这个值就是弱选择性(或其他任何你想到的值)。尽管如此,实际上限制的范围通常是0.05~0.25。如图13-1所示,你只能确认接近0或1的值。



重点需要明白要决定一个操作的类别,与它返回的行数完全无关,只与选择性有关。例如,一个操作返回500000行与选择的访问路径完全无关。相反,一个操作的选择性为0.001,可以明确地把它放在强选择性类别中。

类别对于选择访问路径的类型很重要,它关联着高效的执行计划。图13-2概括地将选择性与访问路径关联在一起,通常来说这是最优化的方式。当使用合适的索引时,可以高效地执行强选择性操作。在本章稍后的部分,可以看到在一些场景中rowid访问或散列群集也可能会有帮助。另一方面,通过读取全表,可以高效执行弱选择性操作。在这两种可能性之间,分区表和散列群集扮演着重要的角色。



注意将数据存储在Exadata存储服务器上时,使用smart scan操作可以利用存储索引(storage index)来减少从磁盘物理读取的数据量。因此,一些平衡选择性的操作或者强选择性的操作,可以高效执行读取全表。我们不能控制存储索引,它们由Exadata存储服务器自动管理。

1.1.1.1   取回单行

这个实验使用access_structures_1.sq1脚本,目的是用取回一行数据所需要的逻辑读数与以下适当的访问结构进行对比:

Ø  带有主键 (primary key) 的堆表 (heap table)

Ø  索引组织表 (index_organized table)

Ø  主键作为群集键 (cluster key) 的单表散列群集 (single-table hash cluster)

注意 本章只介绍处理SQL语句期间如何利用不同类型的段(比如表、群集和索引)最小化逻辑读。可以在Oracle Database Concepts手册中找到它们的基本信息,尤其是“Schema Objects”这一章。

下面是用于实验的查询。请注意,id列是这个表的主键。存在值为6的行,并且rid变量保存着对应行的rowid:

select  *  FROM  sales  WHERE  id  =6;