MySQL多索引查询选择

MySQL选择索引-引入

我们知道我们一个表里面可以有多个索引的,那么我们查询数据的时候不指定索引,MySQL就会帮我们自动选择。既然是MySQL程序帮我们自动选择的那么会不会有问题的呢?答案是会的,MySQL的优化器也有bug,有时候选择的索引并不是最优的。

案例1

假如一张表有10w的数据,有id主键和a,b普通索引,执行以下SQL

select * from t where a between 10000 and 20000; 

select * from t force index(a) where a between 10000 and 20000;

在一定的前提下

执行第一句代码走的是全表查询,扫描了10w行

执行第二句,强制使用a索引,只扫描了10001行

为啥会出现这种情况呢?我们就从优化器的逻辑开始研究

优化器的逻辑

优化器优化判断的指标

有需要扫描的行数,是否使用临时表,是否排序等因素

扫描行数判断

上面的案例明显就是扫描行数的问题

那么优化器是怎么获取扫描的总行数的,其实就和抽样检查类似,因为索引是有序的,就可以使用采样统计这种算法算出大概的扫描行数,可以通过show index查看索引的Cardinality预估值。

案例分析

我们通过explain来查看案例的扫描行数的预估值

rows字段就是预计的扫描行数,可见第二个选择a索引查询的预估扫描行数存在比较大的偏差

问题?

根据结果我们发现走a索引就算是扫描3w7行,也还是比10w快啊,为啥还是选择了全表扫描,因为我们只考虑了扫描行数却没有考虑到回表这个操作,如果加上回表的一些操作那么优化器就会认为还不如走全表查询来的快,所以优化器选择了全表查询。

解决

我们知道问题出在了扫描行的预估不正确,要是出现预估和现实差别比较大的情况的就可以使用analyze table zx的命令来重新预估来改变。

案例2

还是上面的表数据的格式是(1,1,1),10w条

select * from  (select * from t where (a between 1 and 1000)  and (b between 50000 and 100000) order by b limit 100)alias limit 1;

explain

又又又选择错了

原因

为啥会选错呢,其实主要就是时排序的问题,优化器认为按索引a查询出来的数据b不是有序的,还要排序(其实是有序的),所以它选择了b索引,查询出来的数据直接就是有序的,效率会更高

怎么避免这些错误选择索引呢

1.直接force index直接强制指定查询使用的索引

2.analyze table zx重新计算预估的扫描行

3.引导sql的索引选择,比如order by

4.合理设置索引

5......................

参考链接

https://time.geekbang.org/column/article/71173

MySQL多索引查询选择的更多相关文章

  1. mysql之索引查询1

    一 备份数据 备份库: mysqldump:拷贝数据 --database:数据库 基本语法是:mysqldump -h服务器名 -u用户名 -p密码 --database 库名 > 备份路径. ...

  2. mysql之索引查询2

    一 索引的创建 索引减慢了 写的操作,优化了读取的时间 index:普通索引,加速了查找的时间. fulltext:全文索引,可以选用占用空间非常大的文本信息的字段作为索引的字段.使用fulltext ...

  3. MySQL之索引(四)

    压缩索引 MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能.默认只压缩字符串,但通过参数设置也可以对整数做压缩. MyISAM压缩每个索引块的方 ...

  4. MySQL的索引优化,查询优化

    MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. MySQL逻辑架构,来自:高性能MySQL My ...

  5. MySQL数据库索引:索引介绍和使用原则

    本篇目录: 一.数据页与索引页 二.聚簇索引与非聚簇索引 三.唯一索引 四.索引的创建 五.索引的使用规则 六.数据库索引失效情况 本篇正文: 一.数据页与索引页 数据库的表存储分为数据页存储和索引页 ...

  6. 高性能MySQL之索引深入原理分析

    一.背景 我们工作中经常打交道的就是索引,那么到底什么是索引呢?例如,当一个SQL查询比较慢的时候,你可能会说给“某个字段加个索引吧”之类的解决方案. 总的来说索引的出现其实就是为了提高数据查询的效率 ...

  7. mysql使用索引优化查询效率

    索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没 ...

  8. mysql 查询表结构 查询索引

    首先进入到mysql里 show databases; 选择数据库 use xxxcms; 查询数据库下的表结构 show create table 表名; 这样看着不太好可以后面加\G show c ...

  9. Mysql 版本号、存储引擎、索引查询

    [1]Mysql 版本号.存储引擎.索引查询 # 查看数据库版本号 SELECT VERSION(); # 查看数据库支持的引擎(默认即Support == DEFAULT行) SHOW ENGINE ...

随机推荐

  1. windows下搭建开发环境

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...

  2. Exceptionless—本地部署

    参考:https://blog.csdn.net/shiyaru1314/article/details/76176236 自己采坑: ES 1.7.5版本不好使.使用最新版本6.X以上版本也不行 用 ...

  3. [翻译]——MySQL 8.0 Histograms

    前言: 本文是对这篇博客MySQL 8.0 Histograms的翻译,翻译如有不当的地方,敬请谅解,请尊重原创和翻译劳动成果,转载的时候请注明出处.谢谢! 英文原文地址:https://lefred ...

  4. Feeling after reading《Jane Eyre》

    Yesterday I read and listened over the book named <Jane Eyre>, the book is very thoughtful, th ...

  5. RTKLib的Manual解读

    Key-word: integer ambiguity resolution :整周模糊度解算 navigation:导航 Kinematic:动态,RTK的K rover:漫游 validation ...

  6. Python SQLAlchemy入门教程

    本文将以Mysql举例,介绍sqlalchemy的基本用法.其中,Python版本为2.7,sqlalchemy版本为1.1.6. 一. 介绍 SQLAlchemy是Python中最有名的ORM工具. ...

  7. sshd服务以及基于口令的远程登陆

    ssh用为客户端,主要进行服务器端的连接:sshd用为服务器端 几个常用的命令: systemctl              ##服务控制命令   systemctl start sshd   ## ...

  8. git下载安装

    git是目前最流行的分布式版本控制系统,使用它可以很方便的对项目进行管理备份. 1.git下载 登录git官网https://git-scm.com/,点击downloads即可下载安装包 安装包如下 ...

  9. 期末考试(正解:三分单峰函数 me~)

    好久没有水过杂题了! 今天lsc终于刚过了三道考试题来水杂题了! 期末考试 首先一看还是一脸mb(这是正常现象,毕竟我不像一些大神可以一眼出正解)然后我就被颓了标签,知道是三分单峰函数,但是自己实在是 ...

  10. 使用springcloud开发测试问题总结

    使用springcloud开发测试 如下描述的问题,没有指明是linux部署的,都是在windows开发环境上部署验证发现的. Issue1配置客户端不使用配置中心 问题描述: 配置客户端使用配置中心 ...