基于代价的优化方式

  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)

    1. 选择性(Selectivity):是指施加制定谓词条件后返回结果集的记录数占未施加任何谓词条件的原始结果集的记录数的比率。选择率的值越大,就意味着返回结果集的 Cardinality 值就越大,所以估算出来的成本值也就越大。


      选择率的计算公式

         目标列上没有直方图且没有NULL值的情况下,对目标列做等值查询时
      
             Selectivity = 1 / NUM_DISTINCT
             ※ NUM_DISTINCT表示目标列的distinct值的数量
      

    2. 集的势(Cardinality):指集合所包含的记录数。实际上表示对目标 SQL 某个具体执行步骤的执行结果所包含记录数的估算。某个执行步骤的 Cardinality 值越大,那么它所对应的成本值也就越大,这个执行步骤所对应的执行路径总成本值也就越大。


      CBO 估算 Cardinality 公式

             Computed Cardinality = Original Cardinality * Selectivity
             ※ Computed Cardinality:施加指定谓词条件后返回结果集的记录数
             ※ Originad Cardinality:未施加任何谓词条件的原始结果集的记录数
             ※ Selectivity:选择率
      

  • 计划生成器(Plan Generator)
    计划生成器会考虑可能的访问路径(Access Path)、关联方法和关联顺序,生成不同的执行计划,让查询优化器从这些计划中选择出执行代价最小的一个计划。
    query Optimizer Components

CBO 的局限性

  1. CBO 会默认目标 SQL 语句 where 条件中出现的各列之间是独立的,没有关联关系
  2. CBO 会假设所有的目标 SQL 都是单独执行的,并且互不干扰
  3. CBO 对直方图统计信息有诸多限制
  4. CBO 在解析多表关联的目标 SQL 时,可能会漏选正确的执行计划