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. SVN的“Invalid authz configuration”错误的解决方法

    公司有人离职后,我把他svn账号删除 然后就报这个错了,我检查了authz文件,完全看不出什么错误.... 网上的各种方法试一遍,无果. 蹲个厕所,继续查这个问题 看到一个答案: 给不存在的组配置权限 ...

  2. svn配置多仓库与权限控制

    telnet: connect to address 47.106.115.228: Connection refused svn执行上下文错误由于目标计算机积极拒绝无法连接 标签: svn 2017 ...

  3. Linux虚拟机磁盘扩容

    扩容步骤如下: 1.添加一块物理硬盘 2.fdisk将硬盘分区,选primary分区,创建1-4个 3.分区类型格式化,选择t,输入LVM代号 4.分好后按w退出 如果是调整原有逻辑卷大小,则先调整原 ...

  4. 28-组合数(dfs)

    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=32 组合数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 ...

  5. hash+链表

    简单的hash就是用数组加链表的组合来实现,这种hash很简单,但hash的思想在那. #ifndef _HASH_H_ #define _HASH_H_ typedef struct _ListNo ...

  6. sqlserver全备份,差异备份和日志备份

      差异备份是以上一个全备为基点,这个期间所有差异数据的备份. 日志备份是基于前一个全备+日志备份为基点,这个期间的事务日志的备份.(日志备份用于确保还原数据库到某个时间点)   在利用全备+日志备份 ...

  7. (转).Net有哪些大型项目、大型网站的案例?

    [分享].Net有哪些大型项目.大型网站的案例?   .Net开发的部分知名网站案例:http://www.godaddy.com  全球最大域名注册商http://www.ips.com  环迅支付 ...

  8. [SoapUI] 通过Groovy写文本文件

    如果文件已经存在,先删除,然后向文件中追加失败信息 if(maxRecordFail>0){ def testResultFile = new File(projectDir+"\\T ...

  9. 使用BBED理解和修改Oracle数据块

    1.生成bbed list file文件: SQL> select file#||' '||name||' '||bytes from v$datafile; $ vim dbfile.txt ...

  10. java中super的用法

    在Java中,super关键字有2个用法,一个是访问父类的函数,一个是访问父类的变量,总体来说,就是一个功能,访问父类的成员. 代码如下: class Person { String name ; i ...