Mysql中索引的最左前缀原则图文剖析(全)
目录
- 前言
- 1. 定义
- 2. 全索引顺序
- 3. 部分索引顺序
- 3.1 正序
- 3.2 乱序
- 4. 模糊索引
- 5. 范围索引
前言
之所以有这个最左前缀索引
归根结底是mysql的数据库结构 B+树
在实际问题中 比如
索引index (a,b,c)有三个字段,
使用查询语句select * from table where c = '1'
,sql语句不会走index索引的
select * from table where b =‘1’ and c ='2'
这个语句也不会走index索引
1. 定义
最左前缀匹配原则:在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配
为了更好辨别这种情况,通过建立表格以及索引的情况进行分析
2. 全索引顺序
建立一张表,建立一个联合索引,如果顺序颠倒,其实还是可以识别的,但是一定要有它的全部部分
- 建立表
CREATE TABLE staffs(id INT PRIMARY KEY AUTO_INCREMENT,`name` VARCHAR(24) NOT NULL DEFAULT'' COMMENT'姓名',`age` INT NOT NULL DEFAULT 0 COMMENT'年龄',`pos` VARCHAR(20) NOT NULL DEFAULT'' COMMENT'职位',`add_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT'入职时间'
)CHARSET utf8 COMMENT'员工记录表';INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('z3',22,'manager',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('July',23,'dev',NOW());
INSERT INTO staffs(`name`,`age`,`pos`,`add_time`) VALUES('2000',23,'dev',NOW());
- 建立索引
ALTER TABLE staffs ADD INDEX index_staffs_nameAgePos(
name,
age,
pos);
索引的顺序位name-age-pos
显示其索引有没有show index from staffs;
通过颠倒其左右顺序,其执行都是一样的
主要的语句是这三句
explain select *from staffs where name='z3'and age=22 and pos='manager';
explain select *from staffs where pos='manager' and name='z3'and age=22;
explain select *from staffs where age=22 and pos='manager' and name='z3';
以上三者的顺序颠倒,都使用到了联合索引
最主要是因为MySQL中有查询优化器explain,所以sql语句中字段的顺序不需要和联合索引定义的字段顺序相同,查询优化器会判断纠正这条SQL语句以什么样的顺序执行效率高,最后才能生成真正的执行计划
不论以何种顺序都可使用到联合索引
3. 部分索引顺序
3.1 正序
如果是按照顺序(缺胳膊断腿的),都是一样的
- explain select *from staffs where name=‘z3’;
- explain select *from staffs where name='z3’and age=22;
- explain select *from staffs where name='z3’and age=22;
其type都是ref类型,但是其字段长度会有微小变化,也就是它定义的字长长度变化而已
3.2 乱序
如果部分索引的顺序打乱
- 只查第一个索引
explain select *from staffs where name='z3';
- 跳过中间的索引
explain select *from staffs where name='z3' and pos='manager';
- 只查最后的索引
explain select *from staffs where pos='manager';
可以发现正序的时候
如果缺胳膊少腿,也是按照正常的索引
即使跳过了中间的索引,也是可以使用到索引去查询
但是如果只查最后的索引
type就是all类型,直接整个表的查询了(这是因为没有从name一开始匹配,直接匹配pos的话,会显示无序,)
有些时候type就是index类型,这是因为还是可以通过索引进行查询
index是对所有索引树进行扫描,而all是对整个磁盘的数据进行全表扫描
4. 模糊索引
类似模糊索引就会使用到like的语句
所以下面的三条语句
如果复合最左前缀的话,会使用到range或者是index的类型进行索引
explain select *from staffs where name like '3%';
最左前缀索引,类型为index或者rangeexplain select *from staffs where name like '%3%'
; 类型为all,全表查询explain select *from staffs where name like '%3%';
,类型为all,全表查询
5. 范围索引
如果查询多个字段的时候,出现了中间是范围的话,建议删除该索引,剔除中间索引即可
具体思路如下
建立一张单表
CREATE TABLE IF NOT EXISTS article(id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,author_id INT(10) UNSIGNED NOT NULL,category_id INT(10) UNSIGNED NOT NULL,views INT(10) UNSIGNED NOT NULL,comments INT(10) UNSIGNED NOT NULL,title VARCHAR(255) NOT NULL,content TEXT NOT NULL
);INSERT INTO article(author_id,category_id,views,comments,title,content)
VALUES
(1,1,1,1,'1','1'),
(2,2,2,2,'2','2'),
(1,1,3,3,'3','3');
经过如下查询:
explain SELECT id, author_id FROM article WHERE category_id = 1 AND comments > 1 ORDER BY views DESC LIMIT 1;
发现其上面的单表查询,不是索引的话,他是进行了全表查询,而且在extra还出现了Using filesort等问题
所以思路可以有建立其复合索引
具体建立复合索引有两种方式:
create index idx_article_ccv on article(category_id,comments,views);
ALTER TABLE 'article' ADD INDEX idx_article_ccv ( 'category_id , 'comments', 'views' );
但这只是去除了它的范围,如果要去除Using filesort问题的话,还要将其中间的条件范围改为等于号才可满足
发现其思路不行,所以删除其索引 DROP INDEX idx_article_ccv ON article;
主要的原因是:
这是因为按照BTree索引的工作原理,先排序category_id,如果遇到相同的category_id则再排序comments,如果遇到相同的comments 则再排序views。
当comments字段在联合索引里处于中间位置时,因comments > 1条件是一个范围值(所谓range),MySQL无法利用索引再对后面的views部分进行检索
,即range类型查询字段后面的索引无效。
所以建立复合索引是对的
但是其思路要避开中间那个范围的索引进去
只加入另外两个索引即可create index idx_article_cv on article(category_id, views);
Mysql中索引的最左前缀原则图文剖析(全)相关推荐
- MySQL 覆盖索引、最左前缀原则、索引下推
1.覆盖索引 1.1 概念 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了.如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引 ...
- mysql索引优化原则:覆盖索引、最左前缀原则、索引下推
文章目录 前言 round1:覆盖索引 round2:最左前缀原则 round3:索引下推 小结 前言 在文章开始前,小编提出几个问题,读者可以思考一下如何回答.如果对于以下的问题,回答的模棱两可甚至 ...
- 《MySQL实战45讲》——学习笔记04-05 “深入浅出索引、最左前缀原则、索引下推优化“
04 | 深入浅出索引(上) 1. 什么是索引? 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样,书有500页,每页存的都是书的内容,目录可能只有5页,只存了页码:通过目录能快速找到某个主 ...
- 【MySQL】索引原理(三):联合索引(最左前缀原则),覆盖索引,索引条件下推
准备工作,下面的演示都是基于user_innodb表: DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` big ...
- 数据库性能优化1——正确建立索引以及最左前缀原则
1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...
- 数据库正确建立索引以及最左前缀原则
数据库正确建立索引以及最左前缀原则 转自:https://blog.csdn.net/zhanglu0223/article/details/8713149 1. 索引建立的原则 用于索引的最好的备选 ...
- 正确建立索引以及最左前缀原则
1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...
- 索引原理:联合索引(最左前缀原则)
准备工作,创建数据表user_innodb表 DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` bigint(6 ...
- innodb组合索引的最左前缀原则
我们在使用数据库的时候,为了增加访问速度,经常会给某张表增加一些索引.单列索引我之前已经写过一篇文章提过,今天我们主要讲一下怎么使用多列索引,和多列索引的最左前缀原则. 关于最左前缀的误解 早些年读高 ...
最新文章
- Discuz DB层跨库映射关系表名前缀BUG修复后产生的新bug
- 转载:vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 从腾讯朋友圈揭秘内部AI部门竞争关系,谁能像微信当年一样熬出头? By 微胖2017年11月10日 09:06 撰文 | 宇多田 在腾讯合作伙伴大会上,腾讯首席运营官任宇昕提出的「AI in All」
- 2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效
- Maximum upload size exceede上传文件大小超出解决
- cognito_将Spring Boot应用程序与Amazon Cognito集成
- VB调用VC DLL函数
- 如何用 javascript 做一个高逼格的进度条
- css3中的动画学习分享
- 深入研究memcache 特性和限制
- postgres 禁止远程登录_解决postgresql无法远程访问的情况
- testNG-失败用例重跑机制
- 动森11月19日服务器维护,动物森友会11月19日更新内容介绍
- 安装及创建python虚拟环境
- 如何在ppt中插入pyecharts生成的html图表(及可能的报错解决方法)
- Python3的unichr()消失了?不,升级了!
- 数据结构----复习题
- base64图片压缩到指定大小
- 微信小程序在线考试项目开发-接口封装调用
- 用迭代法求 x=根号a。求平方根的迭代公式为:X(n+1)=(Xn+a/Xn) /2。要求前后两次求出的x的差的绝对值 小于10的-5次方
热门文章
- KNIME服务器相关接口的实现
- 什么是polyfill?
- Hibernate4实战 之 第一部分:Hibernate入门
- 操作系统模拟公交车司机与售票员进程之间的协同关系
- phpexcel列数太多,【PHPEXECL】关于使用phpExecl导出数据时,列数超过26个报错问题
- asp.net ajax怎样传值,JQuery在asp.net中三种ajax传值
- flinksql的primary key异常处理
- Swift 版本相册,防微信相册
- Selenium Webdriver学习记录(一):环境搭建(Java+Maven+Eclipse+Selenium3.x)+第一个测试demo+部分问题解决
- A013-animator资源