概述
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、表的选择性
object_id 选择性 1/74895=0.000013352 选择性高---->适合B-tree 索引
owner 选择性 1/27=0.037037037 选择性低---->不适合B-tree 索引
geneated 选择性 1/2=0.5 选择性很低---->不适合B-tree 索引
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
这里可以看到基数为98行。
【重要】:基数 = 记录数 * 选择率
索引---clustering factor
聚簇因子是基于表上索引列上的一个值,每一个索引都有一个聚簇因子。这是用于描述索引块上与表块上存储数据在顺序上的相似程度,也就说表上的数据行的存储顺序与索引列上顺序是否一致。
查看聚簇因子
select index_name,clustering_factor from user_index where table_name='T';在全索引扫描中,CF的值基本上等同于物理I/O或块访问数,如果相同的块被连续读,则Oracle认为只需要1次物理I/O。
好的CF值接近于表上的块数,而差的CF值则接近于表上的行数。
聚簇因子在索引创建时就会通过表上存在的行以及索引块计算获得。
今天这里主要讲了三个重要概念:selectivity、cardinality和CF,可能比较少听到,不过还是建议理解下,对于优化还是很有帮助的。
后面会分享更多DBA方面内容,感兴趣的朋友可以关注下!