博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mysql索引的要点分析
阅读量:6229 次
发布时间:2019-06-21

本文共 3045 字,大约阅读时间需要 10 分钟。

hot3.png

mysql的索引并不是很好总结,所以日常工作中大家应该多使用 explain 来优化自己的查询和索引,做到用最少的索引来配合最高效的查询语句完整业务需求,这里我总结一些平日里遇到的比较多变的索引问题:组合索引的设计问题, order by 如何利用索引

1、最左前缀原则

    应用场景:频繁对多列进行联合检索,可做组合索引

    164112_A6V4_252076.jpg

    例如我们创建了 name email nick 的组合索引 name_email_nick

    要想使用此索引则必须遵循 最左前缀 原则,说的简单些就是 检索条件集 可以从左到右的优先级次序匹对 组合索引的列序

    164757_L8rI_252076.jpg

    可以看出组合索引其实是为每一个子列建立的索引,然后以 seq_in_index 的位序连接在一起,当你想让自己的查询能启用此索引,则最基本的一条就是最左前缀,按位序可以依次满足,中间不存在位序间断

    拿此例来说,左前缀的组合方式有(注意,这里是条件集的最终拼接结果,并不是条件位序):

1    1,2    1,2,3

    而

2    3    2,3

    都不满足最左前缀原则

    实例:

    name 使用一个

    170718_IOoV_252076.jpg

    name email 使用两个

    170755_GEoc_252076.jpg

    name email nick 使用三个

    170817_7Jtj_252076.jpg

    再次强调最左前缀与检索条件的书写顺序无关,只要能满足从左开始不间断的满足组合索引的子列位序即可

    171539_4vBH_252076.jpg

    如上图所示,检索条件的位序虽然与组合索引的不同,但并不影响

    最左前缀:检索条件集合可以按组合索引列序无间断的排列出连续的位序列,则可使用此索引,否则无法使用此索引

    101037_DFEN_252076.jpg

    如上图所示,检索条件只有 email 和 nick,无法有序的组成复合组合索引 name email nick 的不间断序列,缺失 name 位序,所以无法使用索引

    101439_xDo8_252076.jpg

加上 name 即可使用

2、最小资源原则

    这个比较容易理解,mysql 会优先使用 精确度高 的索引,因为每次查询只能使用一个索引,所以这里会有择优算法

    101644_AFzf_252076.jpg

    虽然检索条件符合 primary key 和 name_email_nick 的组合索引使用条件,但主键可以精准定位一条记录所以会使用 主键 而非 组合索引列,这里也再次证明 检索条件的位序和索引位序没什么关系

3、组合索引的本质

    组合索引的本质其实是mysql为每组合列各添加索引,然后用位序标定他们,组合索引其中的某列索引 和 为此列单独添加的普通索引本质上没有区别,如下:

    我先添加的 name_email_nick 组合索引

    我再为 name 列单独添加一普通索引

    102054_iaNl_252076.jpg

    103344_9Ga8_252076.jpg

    我删掉 name_email_nick 组合索引然后再添加它,这样就相当于 普通的 name 索引时序先于 含有 name 的组合索引了

    103509_j1NS_252076.jpg

    103621_wBxA_252076.jpg

    因为我的查询条件只有 name,所以对普通索引 name 和 组合索引 name_email_nick 来说他们所能定位的资源精确度是相等得,而后普通索引 name 与 组合索引中的 name列索引此时属于对等,所以 mysql 就按照谁先创建的就使用谁,此时如果使用 name_email_nick 其实也只是使用其中的 name 列索引,和我们后来添加的 name 的普通索引本质上没有任何区别

4、索引优化之 order by

    网上很多博文说如果检索中有使用 order by 进行检索时,在 order by 列上加索引就会被启用,但据我实测,order by 会使用索引只有以下几种情况

    首先明确,每一次的检索 mysql 只会选用一个索引

    1、当 order by 与 limit 结合时也会有可能启用索引,是有可能,因为 limit 其本质上是在我 order by 的结果集上做范围查询,但也是有限定范围的,当你的 limit 跨度太大mysql仍然不会使用索引,因为代价几乎与Using filesort对等了

   2、 还有一种情况就有些没逻辑了:当 select 的字段与 order by 字段完全吻合时会使用索引......这点我也不知道怎么讲,但 select col from table order by col;真的会使用 col 的索引,即便你不与 limit 联合使用

    3、至于很多人说在 order by 作用的列上加索引就会被启用,那应该是他们的sql中在 where 条件里有 相同列 而已,真正的索引是在 where 里被启用而不是 order by

    143945_RERl_252076.jpg

    索引建立如下

    144202_HYuL_252076.jpg

    1、不配合范围或等值查询,完全查询本表,不启用索引

        网上很多博文说 order by 所作用的列如果有索引便会启用,其实是不准确的,他们得出的结论其实是被 where 条件中的列索引影响了

        144534_Oud6_252076.jpg

        145320_ZQFR_252076.jpg

        但如果你只是选择读取与order by 一致的列则可以启用索引

        151519_pYBR_252076.jpg

        那怎样在日常较为普遍的查询中优化 order by 呢,简单,在 order by 作用的列上加索引后 使用  limit 做辅助查询,但这个范围不能太大,否则索引和遍历整张表没什么区别了,这也是分页的精髓所在,因为 limit 也是一范围,会使用 BTREE 索引做范围查询

         144522_SjF2_252076.jpg

    2、与 where 联用

    感觉与where联用不联用没什么要说的,你只要记住mysql每次查询时只会使用一个索引,如果where中启用索引了order by 即便和 limit 联合也会使用 Using filesort 了

5、使用索引需要注意的几点

    常用索引方式分为 HASH 索引 和 B-TREE 索引

     HASH 索引

    HASH 索引即散列索引,通过散列函数准确的定位出地址,仅适用于 MEMORY 引擎的的表,是无序的,通过 HASH 函数计算出其在内存中的位置,所以只能做精确的=值查询,没办法高效的做范围查询。

    B-TREE 索引

    B-TREE 索引则是有序的,适合 MyISAM InnoDB等引擎,可以做=值,范围(>, <, >=, <=, between, in,limit),但不支持 not in, <> 等查询,因为不等查询肯定会遍历全表,只有遍历到最后一条记录时我才能确定本表中还有无与条件相符的记录。

    索引使用注意项

    1、索引不作用于存在 NULL 值的列,所以建议大家在定义列时指定 NOT NULL DEFAULT val

    2、索引不作用于参与函数运算的列 , 即便 BIRTHDAY 上加了索引,但函数作用在此列上索引失效

SELECT * FROM TABLE WHERE BIRTHDAY >= UNXI_TIMESTAMP('1990-03-07');

    3、索引可以做 等值 范围 查询,不可做不等查询

/*无法启用索引*/SELECT * FROM TABLE WHERE ID <> 1;SELECT * FROM TABLE WHERE ID NOT IN(1, 3, 5, 7);

    4、like 做模糊查询时

/*可使用索引*/SELECT * FROM TABLE WHERE `name` LIKE 'sallen%';/*不可使用索引*/SELECT * FROM TABLE WHERE `name` LIKE '%sallen%';

    5、经常与其他表进行连接的表,在连接字段上应该建立索引

    6、频繁进行数据操作的表,不要建立太多的索引,因为 增删改 都会对索引做更新,这样会加重mysql的负担

    

转载于:https://my.oschina.net/sallency/blog/624634

你可能感兴趣的文章
浅谈linux读写同步机制RCU
查看>>
三层架构设计理念
查看>>
spring的@Transactional
查看>>
java 中生成随机验证码
查看>>
计划任务启动停止控制台程序
查看>>
04-单表查询
查看>>
[ZJOI2006]皇帝的烦恼
查看>>
HTML5简介
查看>>
Read All About It-Attraction舞团
查看>>
[摘录]第1章 开局谈判技巧
查看>>
as 运算符
查看>>
基本数据类型对象包装类
查看>>
1178:成绩排序
查看>>
php总结8——mysql函数库、增删改
查看>>
20170914-构建之法:现代软件工程-阅读笔记
查看>>
HDU5616 天平能否称出物体重量问题 01背包变形或者折半搜索
查看>>
关于group by 两个或以上条件的分析
查看>>
低功耗蓝牙BLE外围模式(peripheral)-使用BLE作为服务端
查看>>
二分法详解
查看>>
Chisel3 - Tutorial - Functionality
查看>>