我的知识海洋

What are you following

  • 首页
  • 标签
  • 分类目录
  • 文章归档
  • 行路万里
  • 读书万卷
  • About Me

  • 搜索
面经 解决方案 操作系统 Java源码 开源 GSoC 哲学 中间件 回溯 链表 书 top 数据库 分布式 滑动窗口 配置 动态规划 前缀树 并查集 Redis 总结 年终总结 面试 算法基础

【MySQL 45讲-10】第10讲MySQL如何选择索引

发表于 2022-02-27 | 分类于 学习 | 阅读次数 1177
# 数据库
【MySQL 45讲-9】第9讲普通索引和唯一索引
【MySQL 45讲-11】第11讲 怎么给字符串字段加索引

请添加图片描述

10 | MySQL为什么有时候会选错索引? (可进行项目扩展)

优化器的逻辑

优化器的工作:

​ 选择索引

选择索引

目标: 最小的代价执行

  • 扫描行数
    • 根据统计信息来估算记录数

      • 统计信息不准确,用analyze table来解决
    • 基数越大,索引的区分度越好

      • 基数:一个索引上不同值得个数

        • 使用show index方法查询索引基数
        • MySQL如何得到索引的基数?
          • 采样统计,默认选择N个数据页,统计这些页面上的不同的值,得到平均值再乘以页面数
      • 区分度:统计信息

    • 使用普通索引进行回表也要代价

  • 是否使用临时表
  • 是否排序

索引选择异常和处理

    1. 采用force index强行选择一个索引
    • 弊端:如果索引改名了语句也得改;另外,如果迁移到其他数据库,语法可能会不兼容
    1. 修改语句,引导MySQL使用我们期望的索引
    • 例如:order by b limit 1 改为 order by b,a limit 1

      • 原:优化器选择使用索引b,因为它认为b本身有序(是索引),就可以避免排序,只需遍历
      • 后:要求按照b,a排序,既然如此,主要取决于扫描行数
    1. 新建一个更合适的索引/删除误用索引

举个栗子

在这里插入图片描述

事务A先开启,接着事务B删除数据后重新进行插入然后进行区间查询,然后A才提交,发现优化器检测到扫描行数增加了三倍,而如果没有先开启事务A,只是单独执行事务B则扫描行数没有改变,什么原因?


delete删掉了所有的数据,重新进行插入,看起来是覆盖了原来的数据

but, A开启了事务后并没有进行提交,因此,每一行数据都有 两个版本!!!

这样的话,索引上的数据也有两份!

但要注意一点,主键是根据表的行数来估计的,表的行数,优化器直接用show table status的值

# 数据库
【MySQL 45讲-9】第9讲普通索引和唯一索引
【MySQL 45讲-11】第11讲 怎么给字符串字段加索引

  • 文章目录
  • 站点概览
erdengk

erdengk

91 日志
5 分类
24 标签
RSS
Github E-mail
Creative Commons
友链
  • 星球球友
  • Joey
  • 北松山(itwaix)-TP在职
  • JooKS' Blog-GSoC 2022 Mentor
  • Chever-John-Shein在职
  • 一堆网页小游戏
  • 飞鸟记
0%
© 2019 — 2026 erdengk
由 Halo 强力驱动
陕ICP备2021015348号-1
川公网安备 51011202000481号
轻点广告,请我喝水,非常感谢 (。・ω・。)ノ(*/ω\*)