美文网首页
10讲MySQL为什么有时候会选错索引

10讲MySQL为什么有时候会选错索引

作者: carlclone | 来源:发表于2019-06-26 13:18 被阅读0次

1 使用存储过程生成假数据

delimiter ;;
create procedure idata()
begin
  declare i int;
  set i=1;
  while(i<=100000)do
    insert into t values(i, i, i);
    set i=i+1;
  end while;
end;;
delimiter ;
call idata();

2 会走索引 select * from t where a between 10000 and 20000;
3 一个 mysql 选错索引的案例

image.png

4 slow log 可以查看具体执行情况
5 force index(a)可以强制使用索引
6 set long_query_time=0; 所有语句都会被记录到 slow log
7 slow log 结果

image.png

8 如何查看 slow log
9 对应的是平常 “不断删除历史数据和新增数据”的场景 , 此时会选错索引
10 优化器的目的 , 最小的代价执行语句 , 最小代价 : 扫描行数少 , 则 IO 少,CPU 消耗少
11 优化器其他判断准则 , 是否使用临时表 , 是否需要排序
12 执行语句之前优化器并不能精确判断扫描行数
13 通过使用”区分度”进行预估
14 区分度就是索引上的cardinality(基数) , 越大区分度越好
15 cardinality是通过采样统计取值的 , 并不精确
16 采样统计的方法 : 取n个数据页 , 取不同值数的平均值 , 乘以数据页数量
17 当变更的数据超过1/M的时候会重新采样统计
18 采样统计可存在磁盘中或只存在内存中
19 通过innodb_stats_persistent修改 , on 是持久化,N是20,M是10 , off 是内存中,N是8,M是16
20 采样统计的值还是很容易不准的 , 但大体上依然是差不多的
21 上面那个案例的两个语句的预估行数

image.png
image.png


22 Q1 语句的预估行数是接近的 , 但是 Q2 的预估行数是错误的
23 此时由于优化器还需要考虑回表去扫描的代价 , 并且认为直接扫描主键索引更快 , 因此当不 force index 的时候会用全表扫描 , 但显然从执行时间来看不是最快的

23 但是主要的问题还是错误的预估行数造成的 , 图 1 就没问题啊
24 analyze table t , 重建 统计

image.png

25 另一个案例 , 说明优化器不只通过预估行数来分析
26 select * from t where (a between 1 and 1000) and (b between 50000 and 100000) order by b limit 1;
27 几种解决方案 , 1 修改语义 2 删除不必要的索引 3 force index
28 思考题 : 为什么单独delete的话预估行数正常 , 但session a没提交的时候则不正常 ? 因为session a没提交 , 数据是不能删除的 , 相当于有两份数据

相关文章

  • 丁奇-MySQL实战读书笔记10

    MySQL为什么有时候会选错索引? 1:MySQL选错索引,啥意思? 我们认为使用K索引检索的速度会更快的,但是M...

  • mysql听讲(十)

    本文源自 极客网站 的某知名大佬讲mysql,整理一下心得和重点。 第10节 mysql为什么会选错索引 mys...

  • 10讲MySQL为什么有时候会选错索引

    1 使用存储过程生成假数据 2 会走索引 select * from t where a between 1000...

  • 10 | MySQL为什么有时候会选错索引?

    优化器的逻辑 优化器没有选择正确的索引,force index 起到了“矫正”的作用。 纠正索引:analyze ...

  • 10 - MySQL选错索引

    关键字 索引选择 0.错误情况 首先,建立一个简单的表,表中有 a、b 两个字段,并且分别建立了索引: 然后,我们...

  • mysql选错索引

    为什么会出现选错索引 优化器会判定当前执行的最优方式,主要包括考虑扫描的行数、是否使用临时表、是否需要排序等; 优...

  • 63 MySQL实战性能优化-optimizer_trace

    1,mysql索引性能优化最佳实战 2, 使用索引查询如何避免回表查询 3,为什么查询有时候加了索引也会失效? 4...

  • 【MySQL】10|MySQL为什么有时会选错索引?

    我们都知道在MySQL中一张表可以支持多个索引。但是我们在写sql的时候,并没有主动指定使用哪个索引,也就是说,使...

  • 为何MySQL会选错索引

    在实际的生产环境中,给MySQL的字段加索引让查询的效率更高,我们往往会给MySQL的表字段加索引。MySQL具体...

  • 2. mysql 为什么会选错索引

    上节我们讲了mysql的整体架构,知道了优化器的作用是优化sql,选择索引,生成执行计划。索引是优化器阶段自己选择...

网友评论

      本文标题:10讲MySQL为什么有时候会选错索引

      本文链接:https://www.haomeiwen.com/subject/dkcccctx.html