概述

Oracle数据库中的优化器又叫查询优化器(Query Optimizer)。它是SQL分析和执行的优化工具,它负责生成、制定SQL的执行计划。Oracle的优化器有两种,基于规则的优化器(RBO)与基于代价的优化器(CBO)

CBO是一种比RBO更加合理、可靠的优化器,它是从ORACLE 8中开始引入,但到ORACLE 9i 中才逐渐成熟,在ORACLE 10g中完全取代RBO, CBO是计算各种可能“执行计划”的“代价”,即COST,从中选用COST最低的执行方案,作为实际运行方案。它依赖数据库对象的统计信息,统计信息的准确与否会影响CBO做出最优的选择。如果对一次执行SQL时发现涉及对象(表、索引等)没有被分析、统计过,那么ORACLE会采用一种叫做动态采样的技术,动态的收集表和索引上的一些数据信息。

针对CBO的计算方式有几个重要概念,下面简单说明下。


选择性selectivity

Selectivity :谓词的过滤条件返回的结果的行数占未加谓词过滤条件的行数

范围0-1,值越小,说明 选择性越好 返回的cardinality 越小;值越大,选择性越差,返回的cardinality 越大。

1、表的选择性

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(1)

object_id 选择性 1/74895=0.000013352 选择性高---->适合B-tree 索引

owner 选择性 1/27=0.037037037 选择性低---->不适合B-tree 索引

geneated 选择性 1/2=0.5 选择性很低---->不适合B-tree 索引

2、索引的选择性

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(2)

inx_t 的选择性 1/74895=0.000013352 选择性很好

ind_t_status 的选择性 1/2=0.5 选择性很不好

3、总结--B-TREE索引

高效的场景– 索引字段有着很高的selectivity或者结果集很小的时候

低效的场景– 索引字段有着很低的selectivity或者结果集很大的时候。


基数cardinality

cardinality代表在执行计划中表示每一步操作返回的记录数。CBO通过对这个值的权重计算,决定使用哪一种方式访问数据。

cardinality和成本是相关的,cardinality越大,执行步骤中的成本就越大。

Cardinality = num_of_blocks * (block_size - cache_layer) / avg_row_len

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(3)

这里可以看到基数为98行。

【重要】:基数 = 记录数 * 选择率


索引---clustering factor

聚簇因子是基于表上索引列上的一个值,每一个索引都有一个聚簇因子。这是用于描述索引块上与表块上存储数据在顺序上的相似程度,也就说表上的数据行的存储顺序与索引列上顺序是否一致。

查看聚簇因子

select index_name,clustering_factor from user_index where table_name='T';

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(4)

在全索引扫描中,CF的值基本上等同于物理I/O或块访问数,如果相同的块被连续读,则Oracle认为只需要1次物理I/O。

好的CF值接近于表上的块数,而差的CF值则接近于表上的行数。

聚簇因子在索引创建时就会通过表上存在的行以及索引块计算获得。

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(5)


今天这里主要讲了三个重要概念:selectivity、cardinality和CF,可能比较少听到,不过还是建议理解下,对于优化还是很有帮助的。

后面会分享更多DBA方面内容,感兴趣的朋友可以关注下!

oracle数据库agent怎么启动(Oracle数据库不为人知的几个概念)(6)

,