ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL索引实现、MySQL索引原理、索引下推、索引覆盖、索引失效

2021-05-13 14:00:31  阅读:347  来源: 互联网

标签:下推 节点 索引 MySQL 失效 where 主键


文章目录

索引实现

https://www.cnblogs.com/jiawen010/p/11805241.html

目前MySQL的Innodb、Myisam存储引擎都是使用的B+树作为存储结构;

但是 memory存储引擎 确是 hash索引,所以索引数据结构要 结合 具体的存储引擎;


InnoDB索引实现

注意:一个索引节点就表示一个磁盘页

InnoDB的主键索引

InnoDB的聚簇索引 的 data域 存的是 行数据(具体数据)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sMwjYEUR-1620884626733)(13DC14EF3A9442128286BAE31CC79783)]

非叶子节点存的是 索引,叶子节点存的是数据;


InnoDB的辅助索引

InnoDB的所有辅助索引 的 data域 存的是 主键

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mHz5XTXi-1620884626737)(3B629EC68CE2496D8BB00F3FBA1F6FFE)]

辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录


MyISAM索引实现

MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNT5Fp98-1620884626738)(AFC02E2F4DB44003868185B63BDF8708)]

在MyISAM中,主键索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复;


Innodb索引和MyISAM索引的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iFsIHrc7-1620884626740)(0C273E2279E748E3834821AD30FE4352)]

  1. Innodb 主键使用的是聚簇索引,MyISam主键索引使用的是非聚簇索引;
  2. Innodb主键索引的叶子节点存放的是行记录,是具体的数据,Innodb非聚簇索引 叶子节点(data域)存放的是主键;而MyISam的聚簇索引和非聚簇索引都存放的是行数据的具体地址;

其它索引数据结构

hash索引的缺点

缺点: 因为底层数据结构是散列的,无法进行比较大小,不能进行范围查找

B+树和二叉查找树的性能对比

B树包括B+树的设计思想都是尽可能的降低树的高度,以此降低磁盘IO的次数,因为一个索引节点就表示一个磁盘页

一个索引节点就表示一个磁盘页;
假设一个节点可以容纳100个值,那么3层的B+树可以容纳100万个数据。
根节点100,第二层100*100,第三次存数据就是100x100x100,z三层只需3次io;

而如果使用二叉查找树,则需要将近20层,也就是进行20次磁盘IO;


B+对比B树的优点

B树的每个节点除了存储指向子节点的索引之外,还有data域,因此单一节点存储的指向子节点的索引并不是很多,树高度较高,磁盘IO次数较多,

个人理解,B树的索引节点,既存索引也存数据,一次io读取的数据是有限的,所以b树存的索引相对于b+树少,在数据量大的情况下,b树io次数多;

假设 一个索引可以存100单位数据,索引和data分别需要1单位,那么3层b树能存50+50x50+50x50*50个索引,而3层b+树可以存100x100x100,故b+树可以存更多索引;

总结:b+树的节点可以存更多索引数据,而b树的节点既要存索引,又要存数据,因此存的索引少;

其它关于索引数据结构的问题

为什么数据库索引不用红黑树而用B+树

红黑树在插入删除操作时需要 通过旋转和变色操作 来恢复二叉树性质;

但是当数据量较小,数据完全可以放入内存中,不需要进行磁盘IO,这时候,红黑树时间复杂度比B+树低。


索引失效

https://www.cnblogs.com/wdss/p/11186411.html

条件中or前后没有同时使用索引,索引失效

例如select * from user where name="zhsngsan" or id=29527;其中id是主键,那么id是主键索引,而name不是索引,则索引失效;

在这里插入图片描述

like 以%开头,索引失效

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7J8m91zo-1620884626743)(43C01175C79542B497BF88341C497E4E)]

当like前缀没有%,后缀有%时,索引有效。

组合索引,不是使用第一列索引,索引失效

https://zhuanlan.zhihu.com/p/108179618

例如 create index test2 on emp(ename , empno,job);,其中ename就是第一列索引,只要条件中不含ename组合索引就会失效;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ibTUXQEc-1620884626743)(4334FEC056244E41B8727FF598B28E06)]

数据类型出现隐式转化,索引失效

如varchar不加单引号的话可能会自动转换为int型,使索引无效;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w6SbE4Gw-1620884626744)(ACCAF859AD184449803B5D2E8AD58B3A)]

其它情况


不推荐使用索引的情况

  1. 数据唯一性差(一个字段的取值只有几种时)的字段不要使用索引

比如性别,只有两种可能数据。意味着索引的二叉树级别少,多是平级。这样的二叉树查找无异于全表扫描。

  1. 频繁更新的字段不要使用索引

比如logincount登录次数,频繁变化导致索引也频繁变化,增大数据库工作量,降低效率。

  1. 字段不在where语句出现时不要添加索引,如果where后含IS NULL /IS NOT NULL/ like ‘%输入符%’等条件,不建议使用索引

只有在where语句出现,mysql才会去使用索引

4) where 子句里对索引列使用不等于(<>),使用索引效果一般



覆盖索引

只需要在一棵索引树上就能获取SQL所需的所有列数据的索引成为覆盖索引(Covering Index),无需回表,速度更快。

//id是主键、name是索引,则下面sql需要回表,因为需要通过id回表获取sex;
select id,name,sex from user where name='shenjian';

但是,如果再创建一个联合索引(name,sex),那么上面的sql就不需要回表;因为通过(name,sex)的索引可以获取id,name,sex 不需要回表;

组合索引

最左匹配原则

https://chensj.blog.csdn.net/article/details/108540362

组合索引abc_index:(a,b,c),只会在where条件中带有(a)、(a,b)、(a,b,c)的三种类型的查询中使用使用索引。

当where条件只有(a,c)时也会走,但是只走a字段索引,不会走c字段。


注意

  • 当遇到范围查询(>、<、between、like)就会停止匹配。
(a,b,c,d)建立索引,  
where后条件为a = 1 and b = 2 and c > 3 and d = 4  
那么,a,b,c三个字段能用到索引,而d就匹配不到。因为遇到了范围查询!

组合索引数据结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OCh7stYQ-1620884626744)(E3042C65C58B417A9E99505B1706E97D)]

联合索引中的索引项会先根据第一个索引列进行排序,第一个索引列相同的情况下,会再按照第二个索引列进行排序,依次类推。

例如联合索引abc_index:(a,b,c),sql where a=1and b=2 and c=3;
先根据a查询,a相同的情况下,b是排好序的,因此可以定位到b,同理c;

但是如果sql是where a=1,c=3;a会走索引得出主键,再根据主键回表查c;
因为a相同时,c是乱序的;

总结
联合索引(a,b,c)可以直接定位到a,ab,abc,至于ac需要2次定位;


索引下推

https://blog.csdn.net/luxiaoruo/article/details/106637231

https://blog.csdn.net/qq_34162294/article/details/105260154

在不使用索引下推的情况下,使用非主键索引进行查询时,存储引擎 通过索引检索到数据,然后返回给MySQL服务器,服务器做最后的筛选

例如查询gander=男 and age>20的数据,
不使用索引下推时,存储引擎将gander=男的数据直接返回 给mysql服务层,再由 服务层 根据age>20筛选出最终数据返回Clint;

使用索引下推后,存储引擎 直接筛选gander=男 and age>20的数据返回 给mysql服务层;


谓词下推

什么是谓词

谓词下推概念中的谓词指返回bool值即true和false的函数,或是隐式转换为bool的函数:

SQL中的谓词主要有 LKIE、BETWEEN、IS NULL、IS NOT NULL、IN、EXISTS。


谓词下推

https://blog.csdn.net/EdwardWong_/article/details/105970779

谓词下推 Predicate Pushdown:基本策略是,始终将过滤表达式尽可能移至靠近数据源的位置。

简而言之,就是在不影响结果的情况下,尽量将过滤条件提前执行。

  • 例如
select count(1) from A Join B on A.id = B.id where A.a > 10 and B.b < 100;

在处理Join操作之前需要首先对A和B执行TableScan操作,然后再进行Join,再执行过滤,最后计算聚合函数返回,但是如果把过滤条件A.a > 10和B.b < 100分别移到A表的TableScan和B表的TableScan的时候执行,可以大大降低Join操作的输入数据。优化后的语句如下:

select count(1) from (select *  from A  where a>10)A1 Join (select *  from B  where b<100)B1 on A1.id = B1.id;

标签:下推,节点,索引,MySQL,失效,where,主键
来源: https://blog.csdn.net/qq_43369986/article/details/116747163

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有