目录

  • 前言
  • 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;

通过颠倒其左右顺序,其执行都是一样的
主要的语句是这三句

  1. explain select *from staffs where name='z3'and age=22 and pos='manager';
  2. explain select *from staffs where pos='manager' and name='z3'and age=22;
  3. 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或者range
  • explain 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等问题

所以思路可以有建立其复合索引
具体建立复合索引有两种方式:

  1. create index idx_article_ccv on article(category_id,comments,views);
  2. 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中索引的最左前缀原则图文剖析(全)相关推荐

  1. MySQL 覆盖索引、最左前缀原则、索引下推

    1.覆盖索引 1.1 概念 索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了.如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引 ...

  2. mysql索引优化原则:覆盖索引、最左前缀原则、索引下推

    文章目录 前言 round1:覆盖索引 round2:最左前缀原则 round3:索引下推 小结 前言 在文章开始前,小编提出几个问题,读者可以思考一下如何回答.如果对于以下的问题,回答的模棱两可甚至 ...

  3. 《MySQL实战45讲》——学习笔记04-05 “深入浅出索引、最左前缀原则、索引下推优化“

    04 | 深入浅出索引(上) 1. 什么是索引? 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样,书有500页,每页存的都是书的内容,目录可能只有5页,只存了页码:通过目录能快速找到某个主 ...

  4. 【MySQL】索引原理(三):联合索引(最左前缀原则),覆盖索引,索引条件下推

    准备工作,下面的演示都是基于user_innodb表: DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` big ...

  5. 数据库性能优化1——正确建立索引以及最左前缀原则

    1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...

  6. 数据库正确建立索引以及最左前缀原则

    数据库正确建立索引以及最左前缀原则 转自:https://blog.csdn.net/zhanglu0223/article/details/8713149 1. 索引建立的原则 用于索引的最好的备选 ...

  7. 正确建立索引以及最左前缀原则

    1. 索引建立的原则 用于索引的最好的备选数据列是那些出现在WHERE子句.join子句.ORDER BY或GROUP BY子句中的列. 仅仅出现在SELECT关键字后面的输出数据列列表中的数据列不是 ...

  8. 索引原理:联合索引(最左前缀原则)

    准备工作,创建数据表user_innodb表 DROP TABLE IF EXISTS `user_innodb`; CREATE TABLE `user_innodb` (`id` bigint(6 ...

  9. innodb组合索引的最左前缀原则

    我们在使用数据库的时候,为了增加访问速度,经常会给某张表增加一些索引.单列索引我之前已经写过一篇文章提过,今天我们主要讲一下怎么使用多列索引,和多列索引的最左前缀原则. 关于最左前缀的误解 早些年读高 ...

最新文章

  1. Discuz DB层跨库映射关系表名前缀BUG修复后产生的新bug
  2. 转载:vs2010 问题 LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  3. 从腾讯朋友圈揭秘内部AI部门竞争关系,谁能像微信当年一样熬出头? By 微胖2017年11月10日 09:06 撰文 | 宇多田 在腾讯合作伙伴大会上,腾讯首席运营官任宇昕提出的「AI in All」
  4. 2.CCGridAction(3D效果),3D反转特效,凸透镜特效,液体特效,3D翻页特效,水波纹特效,3D晃动的特效,扭曲旋转特效,波动特效,3D波动特效
  5. Maximum upload size exceede上传文件大小超出解决
  6. cognito_将Spring Boot应用程序与Amazon Cognito集成
  7. VB调用VC DLL函数
  8. 如何用 javascript 做一个高逼格的进度条
  9. css3中的动画学习分享
  10. 深入研究memcache 特性和限制
  11. postgres 禁止远程登录_解决postgresql无法远程访问的情况
  12. testNG-失败用例重跑机制
  13. 动森11月19日服务器维护,动物森友会11月19日更新内容介绍
  14. 安装及创建python虚拟环境
  15. 如何在ppt中插入pyecharts生成的html图表(及可能的报错解决方法)
  16. Python3的unichr()消失了?不,升级了!
  17. 数据结构----复习题
  18. base64图片压缩到指定大小
  19. 微信小程序在线考试项目开发-接口封装调用
  20. 用迭代法求 x=根号a。求平方根的迭代公式为:X(n+1)=(Xn+a/Xn) /2。要求前后两次求出的x的差的绝对值 小于10的-5次方

热门文章

  1. KNIME服务器相关接口的实现
  2. 什么是polyfill?
  3. Hibernate4实战 之 第一部分:Hibernate入门
  4. 操作系统模拟公交车司机与售票员进程之间的协同关系
  5. phpexcel列数太多,【PHPEXECL】关于使用phpExecl导出数据时,列数超过26个报错问题
  6. asp.net ajax怎样传值,JQuery在asp.net中三种ajax传值
  7. flinksql的primary key异常处理
  8. Swift 版本相册,防微信相册
  9. Selenium Webdriver学习记录(一):环境搭建(Java+Maven+Eclipse+Selenium3.x)+第一个测试demo+部分问题解决
  10. A013-animator资源