识别次优访问路径 1

2023年 12月 9日 58.4k 0

1.1         
识别次优访问路径

通过查看查询优化器的估值和正确识别的限制,判断执行计划是否高效的方法。重点需要明白即使查询优化器正确选择了最优的执行计划,并不代表这个执行计划就会高效执行。也许在修改了SQL语句或访问结构(例如,增加索引)之后,会想到更好的执行计划。

 

1.1.1      识别

最有效的访问路径是能够使用最少的资源来处理数据。因此,要识别访问路径是否高效,可以识别它处理使用的资源数是否可以接受。要做到这些,需要定义如何衡量资源的使用,以及怎样才算是可以接受。此外,还需要考虑检查的可行性。换句话说,也需要考虑执行检查需要做多少工作。它必须尽可能简单。实际上,完善的检查需要花费太多的时间去执行,在实际中这是无法接受的,尤其是需要处理数十甚至数百条等待优化的SQL语句,或者仅仅是因为你工作的时间很紧。

 

作为附注,请记得本节关注的是效率,不仅仅是速度。重点需要知道往往最高效的访问路径并不是最快的。正如第15章所述,使用并行处理时,有时即使使用的资源更多,但也可以获得更好的响应时间。当然,当你考虑整个系统时,SQL语句使用越少的资源(换句话说,效率更高),系统的扩展性就会越高,速度越快。这是因为很显然资源是有限的。

 

作为第一近似值,当访问路径使用的资源数与返回行数(即,返回执行计划里父操作的行数)成正比时,是可接受的。换句话说,当返回少量的行,那么预期的资源使用率会降低,而返回大量行时,资源使用率会升高。因此,检查应该基于返回单行时的资源使用数。

 

理想情况下,你会衡量数据库引擎使用的全部四种资源类型(CPU、内存、磁盘和网络)的消耗。当然,这可以做到,但不幸的是,获取所有这些指标会花费很多时间和精力,并且通常也只对优化会话中一小部分的SQL语句有效。你也应该考虑当处理一行时,CPU处理时间是依赖处理器的速度的,这在系统与系统之间会有明显的不同。进一步讲,内存使用的总数几乎与返回行数成正比,而磁盘和网络并不是总会用到。实际上,长时间运行的SQL语句使用适度的内存量并且没有磁盘或网络访问也不是罕见的。

 

幸运的是,有一个数据库度量很容易收集到,它可以告诉你很多数据库引擎工作的信息:逻辑读数,即,在SQL语句执行期间访问的块数。对于它来说有五个好处。

第一,逻辑读是CPU-bound操作,因此可以很好地反映CPU使用率。

第二,或许逻辑读会导致物理读,因此如果减少逻辑读数,也可能会减少磁盘I/O操作。

第三,逻辑读是序列化操作。由于你经常需要优化多用户负载,最小化逻辑读可以很好地避免扩展性问题。

第四,在SQL语句和执行计划操作级别上,逻辑读数在SQL跟踪文件和动态性能试图中是现成的。

第五,逻辑读数独立于CPU和磁盘I/O子系统的负载。

 

由于逻辑读数很接近整体的资源消耗数,因此你可以主要处理(至少在第一轮优化中)返回的行中有较高逻辑读数的访问路径。下面是一些通常认为好的“经验法则”。

Ø  每行小于5个逻辑读的访问路径基本上是好的。

Ø  每行最多10~15个逻辑读的访问路径基本上可以接受。

Ø  通常认为每行超过20个逻辑读的访问路径是低效的。换句话说,可能有提升的空间。

 

要检查每行的逻辑读数,通常有两种方法。第一,利用动态性能视图提供的执行统计信息,然后通过dbms_xplan包来显示,下面的执行计划是使用这种方法生成的。对于每个操作,你能看到返回的行数(A-Rows列)和为了返回行执行的逻辑读数(buffer列):

第二种方法是利用SQL跟踪提供的信息(第3章已经详细介绍过该技术)。以下代码段引用自TKPROF生成的输出,使用的是与上一个例子相同的查询。请注意,返回行数(Row列)和逻辑读(cr属性)与之前的指标吻合。

Rows    
Row Source Operation

----------------------------------------------------

3       
TABLE ACCESS BY INDEX ROWID T(cr=28 pr=0 pw=0 time=80 us)

24        
INDEX RANGE SCAN T_N2_I(cr=4 pr=0 pw=0 time=25 us)(object id 39684)

 

基于之前提到的经验法则,可以接受这样的执行计划作为例子来使用。实际上,访问路径返回的每行逻辑读数大约是9(28/3)。让我们来看看同样的SQL语句执行计划糟糕时是什么样子。请注意,糟糕是因为访问路径返回的每行逻辑读数是130(390/3),并不是因为它包含全表扫描!

需要再次强调本节是关于访问路径的。因此,你必须仅在访问路径层面考虑这些指标,而不是针对整个SQL语句。实际上,在SQL语句级别上这些指标或许会造成误导。要理解可能发生的问题,让我们来检查以下查询。如果是在SQL语句级别(大概是操作0)上,那么执行了387逻辑读来返回一行数据。换句话说,这会导致错误地将其归类为低效的。

 

然而,如果访问操作的指标(操作2)正确列入考虑范围内,那么逻辑读数(387)和返回行数(160)的比率,会将这个访问路径归类为高效的。本例中的问题是操作1对操作2返回的行使用sum函数。结果,它永远都只会返回单行并且“隐藏”了访问路径的性能指标:

如果你真的只能看SQL语句级别的指标(例如,由于SQL跟踪文件不包含执行计划),那么使用之前提供的经验法会变得很困难,仅仅因为你没有足够的信息。然而,在这种情况下,至少对于简单的SQL语句来说,可以尝试猜测访问路径指标而适应经验法则。比如,可以仔细检查SQL语句是否存在聚合,找出SQL语句中引用了多少张表,然后对应引用表的数量,按比例增加经验法则中的限制。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论