【看懂执行计划】基于成本的优化器(CBO)
基于代价的优化方式(Cost-Based Optimization,简称CBO)
CBO选择目标SQL执行计划的判断原则是成本,从目标SQL的诸多执行计划中选取成本值最小的执行路径为其执行计划,各执行路径的成本值是根据目标SQL中涉及到的表、索引、列等相关对象的统计信息计算出来的,实际反应执行目标SQL所要消耗的I/O、CPU和网络资源的一个估计值。
- I/O
把数据从磁盘读入内存时所需代价(Select重点指标) - CPU
处理内存中数据所需的代价(排序(sort)、连接(join)操作) - 网络资源
网络资源是指那些用了dblink的分布式目标SQL,CBO在解析该类目标SQL时知道在实际执行时所需要的的数据并不在本地数据库中(需要远程数据库取数),便会将网络资源消耗折算成对等的I/O资源消耗再进行估算。 - 动态采样
执行SQL所涉及对象(表、索引等)没有被分析、统计过,Oracle就会使用动态采样,动态的收集表和索引上的一些数据信息,但这些统计信息不会记录在视图中,只在硬解析时才会使用动态采样。
CBO组成
- 查询转化器(Query Transformer)
查询转换器的作用就是等价改变查询语句的形式,以便产生更好的执行计划。
Oracle转换技术:视图合并(View Merging)、谓词推进(Predicate Pushing)、非嵌套子查询(Subquery Unnesting)、物化视图的查询重写(Query Rewrite With Materialized Views) - 代价评估器(Estimator)
评估器通过计算三个值来评估各个执行计划的总体成本:选择性(Selectivity)、集的势(Cardinality)、成本(Cost)
- 选择性(Selectivity):是指施加制定谓词条件后返回结果集的记录数占未施加任何谓词条件的原始结果集的记录数的比率。选择率的值越大,就意味着返回结果集的Cardinality值就越大,所以估算出来的成本值也就越大。
选择率的计算公式
目标列上没有直方图且没有NULL值的情况下,对目标列做等值查询时
Selectivity = 1 / NUM_DISTINCT
※ NUM_DISTINCT表示目标列的distinct值的数量
- 集的势(Cardinality):指集合所包含的记录数。实际上表示对目标SQL某个具体执行步骤的执行结果所包含记录数的估算。某个执行步骤的Cardinality值越大,那么它所对应的成本值也就越大,这个执行步骤所对应的执行路径总成本值也就越大。
CBO估算Cardinality公式
Computed Cardinality = Original Cardinality * Selectivity
※ Computed Cardinality:施加指定谓词条件后返回结果集的记录数
※ Originad Cardinality:未施加任何谓词条件的原始结果集的记录数
※ Selectivity:选择率
- 计划生成器(Plan Generator)
计划生成器会考虑可能的访问路径(Access Path)、关联方法和关联顺序,生成不同的执行计划,让查询优化器从这些计划中选择出执行代价最小的一个计划。
CBO的局限性
- CBO会默认目标SQL语句where条件中出现的各列之间是独立的,没有关联关系
- CBO会假设所有的目标SQL都是单独执行的,并且互不干扰
- CBO对直方图统计信息有诸多限制
- CBO在解析多表关联的目标SQL时,可能会漏选正确的执行计划