• mysql 代价


    mysql cbo cost base optimizer 基于代价,数据是一直变化的
    oracle8 以前是rbo rule base optimizer 基于规则, 如果sql使用了索引,必须使用索引,尽管全表扫描比索引快

    代价= cpu cost + io cost
    1)计算全表扫描代价
      a)cpu cost
        (double) records / TIME_FOR_COMPARE + 1
        records为表会统计的所有记录个数
        TIME_FOR_COMPARE 为5,即CPU每比较5条记录,计1个cost, 是mysql层统计
      b)io cost
        (double) (prebuilt->table->stat_clustered_index_size
        聚簇索引叶页面数

    2)索引范围扫描代价
      a)主键,唯一索引 io cost
        a1)cpu cost
          范围查找估算的记录/TIME_FOR_COMPARE+1
        a2)io cost
          (range+row)/(总记录/聚焦索引的页面数)
          通过范围查找,估算出有100条记录,总记录500条,共有20个page
          那么一个page能装载500/20=25条记录,那100条记录 需要 100/25=4条记录来装载
      b)二级索引覆盖索引
        b1)cpu cost
          范围查找估算的记录数/TIME_FOR_COMPARE+1
        b2)io cost
          范围查找估算的记录数/keys_per_page
      c)二级索引 非覆盖索引
        c1)cpu cost
          范围查找估算的记录数/TIME_FOR_COMPARE+1
        c2)io cost
          范围查找估算的记录数, 需要回表,但可能对应的主键有若干个在同一个page

    关于mysql cost 成本的计算方式,感觉计算过程是不太合理的,也常常是不精确的,计算结果倾向于进

    行全表扫描,在mysql 中,cost 成本模型是分别计算cpu cost 和io cost,然后把两者相加而得到最终的

    总成本, 并没有考虑到CPU&IO 的权重因素、机器CPU 实际处理速度、 IO 的实际能力和当前的负载等因素,

    对这块的统计数据也没有收集操作。

    公式简要说明如下:

    单表时:

    COST = io_cost + cpu_cost;

    | |

    | |

    V V

    read_time + found_records / (double) TIME_FOR_COMPARE==5

    其中的read_time 和found_records 计算过程按不同的type 如下:

    当type 为:

    system & const: //const_tab

    {

    found_records=read_time=1;

    }

    当type 为:

    Index : //covering index

    {

    uint keys_per_block= (index_block_size/2/key_len) + 1); //块一半满,除以键长度

    read_time=((double) (records+keys_per_block-1)/(double) keys_per_block);

    found_records = ranges 区间扫描得到的总行数;(当存储引擎不支持index filter 时,

    为下行扇出的记录条数和)

    }

    当type 为:

    Ref_[OR_null]: //ref

    {

    read_time = found_records + ranges;

    found_records = ranges 区间扫描得到的总行数; (当存储引擎不支持index filter 时,

    为下行扇出的记录条数和)

    }

    DEFAULT:(type 其实为all)

    found_records=全表记录;

    read_time= 全索引pages 数目;

    join时为:

    总cost= 前表cost + 后表cost * 前表found_records

    (采用贪婪算法,找出谁先谁后顺序进行join.)

    估算card 时,部分动作可以触发统计信息的收集,包括analyze、show table status 等,在innodb

    中为8 个分散索引块扫描后计算得到的,也看到有人改为用64 块进行统计信息的收集,同时关闭参数

    innodb_stats_method,以保证执行计划的稳定性。

  • 相关阅读:
    LwIP源代码文件目录解析
    规划2014!
    test
    111
    df
    第一次北京之行
    Android02--debug.keystore的注册信息
    Android01--开发环境搭建
    dfd
    1007
  • 原文地址:https://www.cnblogs.com/taek/p/6580235.html
Copyright © 2020-2023  润新知