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,以保证执行计划的稳定性。

mysql 代价的更多相关文章

  1. mySql---or和in的效率问题(和<=、>=、between之间的关系)

    写在前面: 本文是直接拿取的别人的实验数据作参考,然后对数据作分析. 参考网友的测试数据结果: 在网上一直看到的是or和in的效率没啥区别,一直也感觉是这样,前几天刚好在看<mysql数据库开发 ...

  2. Java 8 为什么会引入lambda 表达式?

    Java 8 为什么会引入lambda ? 在Java8出现之前,如果你想传递一段代码到另一个方法里是很不方便的.你几乎不可能将代码块到处传递,因为Java是一个面向对象的语言,因此你要构建一个属于某 ...

  3. 转载java 8 为什么引入 lambda

    转载:https://www.cnblogs.com/keeya/p/11404631.html 在Java8出现之前,如果你想传递一段代码到另一个方法里是很不方便的.你几乎不可能将代码块到处传递,因 ...

  4. mysql物理优化器代价模型分析【原创】

    1. 引言 mysql的sql server在根据where condition检索数据的时候,一般会有多种数据检索的方法,其会根据各种数据检索方法代价的大小,选择代价最小的那个数据检索方法. 比如说 ...

  5. MySQL为什么"错误"选择代价更大的索引

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 MySQL优化器索引选择迷思. 高鹏(八怪)对本文亦有贡献. 1. 问题描述 群 ...

  6. mysql存储过程的参数名不要跟字段名一样 (血淋淋的代价)

    如题,将会导致的结果就是参数的值将不会是你传入的值,而是变成每条记录的那个字段的值. 这样的后果,是灰常严重的.比如执行删除操作,它能把整个表的记录全删了. 这个是我的血淋淋的代价啊. 死坑如下,勿跳 ...

  7. mysql优化器在统计全表扫描的代价时的方法

    innodb 的聚集索引 的叶子结点 存放的 是 索引值以及数据页的偏移量 那么在计算全表扫描的代价是怎么计算的呢? 我们知道代价 为 cpu代价+io代价 cpu代价 就是 每5条记录比对 计算一个 ...

  8. MySQL常见面试题

    1. 主键 超键 候选键 外键 主 键: 数据库表中对储存数据对象予以唯一和完整标识的数据列或属性的组合.一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null). 超 键: 在关系中 ...

  9. MySQL 优化之 ICP (index condition pushdown:索引条件下推)

    ICP技术是在MySQL5.6中引入的一种索引优化技术.它能减少在使用 二级索引 过滤where条件时的回表次数 和 减少MySQL server层和引擎层的交互次数.在索引组织表中,使用二级索引进行 ...

随机推荐

  1. Codeforces 678E 状压DP

    题意:有n位选手,已知n位选手之间两两获胜的概率,问主角(第一个选手)最终站在擂台上的概率是多少? 思路:一看数据范围肯定是状压DP,不过虽然是概率DP,但是需要倒着推:我们如果正着推式子的话,初始状 ...

  2. Windows 10 归档、对于一些问题的解决与软件推荐

    I'm a Windows Insider 最近加入了 Windows Insider 计划,主要目的还是为了体验一下马上(7.29)就要发售的 Windows 10 操作系统. 先简要介绍下 Win ...

  3. Python实现常见算法[1]——冒泡排序

    #!/usr/bin/python def BUBBLE_SORT(L, x, y): j = y while j>x: i = x while i<j: if L[i] > L[i ...

  4. IOS 获取农历方法(转)

    声明:以下为使用iOS的 NSChineseCalendar 网上之前发现有人说这个方法不是完全准确,有些日期会显示的不对,本人没有验证过,也实在懒得用C++那套方法去实现. 另外我做的不过是个简单的 ...

  5. 解决git无法clone地址为https的库

    一.问题描述 早上在学习<Spark快速大数据分析>的时候,需要下载书本的实例代码,于是用git clone一下给出的库: https://github.com/databricks/le ...

  6. QUrl

    QUrl Detailed Description The QUrl class provides a convenient interface for working with URLs. It c ...

  7. redis缓存分页思路

    传统分页一般分页做缓存都是直接查找出来,按页放到缓存里,但是这种缓存方式有很多缺点.如缓存不能及时更新,一旦数据有变化,所有的之前的分页缓存都失效了.比如像微博这样的场景,微博下面现在有一个顶次数的排 ...

  8. es学习-索引别名

    别名不能重复,也不能喝索引名称重复.(一个索引可以创建多个别名) 语法: 添加一个别名: url:POST http://192.168.0.108:9200/_aliases/ 参数: { &quo ...

  9. Qt资源整理ING

    QCustomPlot:图表库,开源, 链接地址http://www.qcustomplot.com/index.php/download 一些Qt的开发库:http://qt-project.org ...

  10. 大前端涉猎之前后端交互总结2:使用PHP进行表单数据上传与更新

    1:使用PHP进行表单上传 1.1 form表单的数据收集 HTML页面: 代码解释:核心模块是form的属性: --提交方式 :  method="post" --指定 name ...