MySQL多索引查询选择
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多索引查询选择的更多相关文章
- mysql之索引查询1
一 备份数据 备份库: mysqldump:拷贝数据 --database:数据库 基本语法是:mysqldump -h服务器名 -u用户名 -p密码 --database 库名 > 备份路径. ...
- mysql之索引查询2
一 索引的创建 索引减慢了 写的操作,优化了读取的时间 index:普通索引,加速了查找的时间. fulltext:全文索引,可以选用占用空间非常大的文本信息的字段作为索引的字段.使用fulltext ...
- MySQL之索引(四)
压缩索引 MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能.默认只压缩字符串,但通过参数设置也可以对整数做压缩. MyISAM压缩每个索引块的方 ...
- MySQL的索引优化,查询优化
MySQL逻辑架构 如果能在头脑中构建一幅MySQL各组件之间如何协同工作的架构图,有助于深入理解MySQL服务器.下图展示了MySQL的逻辑架构图. MySQL逻辑架构,来自:高性能MySQL My ...
- MySQL数据库索引:索引介绍和使用原则
本篇目录: 一.数据页与索引页 二.聚簇索引与非聚簇索引 三.唯一索引 四.索引的创建 五.索引的使用规则 六.数据库索引失效情况 本篇正文: 一.数据页与索引页 数据库的表存储分为数据页存储和索引页 ...
- 高性能MySQL之索引深入原理分析
一.背景 我们工作中经常打交道的就是索引,那么到底什么是索引呢?例如,当一个SQL查询比较慢的时候,你可能会说给“某个字段加个索引吧”之类的解决方案. 总的来说索引的出现其实就是为了提高数据查询的效率 ...
- mysql使用索引优化查询效率
索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没 ...
- mysql 查询表结构 查询索引
首先进入到mysql里 show databases; 选择数据库 use xxxcms; 查询数据库下的表结构 show create table 表名; 这样看着不太好可以后面加\G show c ...
- Mysql 版本号、存储引擎、索引查询
[1]Mysql 版本号.存储引擎.索引查询 # 查看数据库版本号 SELECT VERSION(); # 查看数据库支持的引擎(默认即Support == DEFAULT行) SHOW ENGINE ...
随机推荐
- 暑期集训20190730 取模(mod)
[题目描述] 给定一个长度为n的非负整数序列a,你需要支持以下操作: 1:给定l,r,输出a[l]+a[l+1]+…+a[r]. 2:给定l,r,x,将a[l],a[l+1],…,a[r]对x取模. ...
- python写购物车小程序
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Author: Skyell Wang # @Time : 2018/5/22 15:50 # 基础要 ...
- N42期-qq-林友埙-第一周作业
1.按系列罗列Linux的发行版,并描述不同发行版之间的联系与区别. 基于Dpkg (Debian系) 商业发行版 o Ubuntu,一个非常流行的桌面发行版. 社区发行版 o Debian,一个强烈 ...
- 20190630模拟赛B(单调队列优化dp)
.dp无疑了其实. 在考场上,我写了一个错解,但是数据小都能过,只是会爆空间,考场上想着怎么用滚动数组优化来着....把错解的方程列出来吧 ;i<=n;i++) { ;j<=k;j++) ...
- SpringBoot 源码解析 (二)----- Spring Boot精髓:启动流程源码分析
本文从源代码的角度来看看Spring Boot的启动过程到底是怎么样的,为何以往纷繁复杂的配置到如今可以这么简便. 入口类 @SpringBootApplication public class He ...
- Netty处理器重要概念
1.Netty的处理器可以分为两类:入站处理器和出战处理器 2.入站处理器顶层是ChannelInboundHandler,出战处理器顶层是ChannelOutboundHandler 3.数据处理时 ...
- 部署django
添加uwagi配置文件 在你项目的根目录中创建mysite.xml(名字无所谓),或者创建mysite.ini,输入以下内容: <uwsgi> <socket>127.0.0. ...
- 小程序 数字过千 以K显示
先新建一个 wxs 文件 每一个 .wxs 文件和 <wxs> 标签都是一个单独的模块. 每个模块都有自己独立的作用域.即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见. ...
- 手把手教你用netty撸一个ZkClient
原文地址: https://juejin.im/post/5dd296c0e51d4508182449a6 前言 有这个想法的缘由是前一阵子突发奇想, 想尝试能不能直接利用js连接到zookeeper ...
- nuxt遇到的问题(一)window 或 document is not defined
因为用了VUE做的官网,既然是官网了避免不了SEO的问题了(该死当初就不应该选择用vue) 很自然就是选择了使用nuxt.js来做ssr预渲染了. 因为网站不是响应式的,PC / 移动端要进行对应跳转 ...