IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 玩转MySQL索引 -> 正文阅读

[数据结构与算法]玩转MySQL索引

目录

索引数据结构

hash表

平衡二叉树

B树

B+树

索引分类

聚簇索引和非聚簇索引

类型区分

索引失效原因

索引调优

索引知识点

回表

索引覆盖

最左匹配原则

索引下推


面试中,经常被问到的MySQL索引是什么数据结构?索引有那些分类? 开发中,经常遇到的明明加了索引,为啥会失效?索引应该怎么调优?

索引数据结构

MySQL索引的作用加快数据访问。

对于索引的设计,我们不妨思考下目前已知的数据结构: hash表、平衡二叉树 (AVL)、B树、B+树。

hash表

如下:数据结构为数据链表

image.png

显而易见,如使用hash表有如下弊端:

1、插入数据的时候存在hash碰撞或者hash冲突,需要设计比较好的hash算法,否则会造成存储空降的浪费;

2、当进行范围查找的时候,必须挨个进行匹配,效率极低,不适合做范围查询;

平衡二叉树

如下:数据结构为平衡二叉树

MySQL数据结构.jpg

一棵平衡二叉树能容纳多少的结点呢?

这跟树的高度是有关系的,假设树的高度为 h,那每一层最多容纳的结点数量为 2^(n-1),整棵树最多容纳节点数为 2^0+2^1+2^2+...+2^(h-1)。

这样计算,100w 数据树的高度大概在 20 左右,也就是说从有着 100w 条数据的平衡二叉树中找一个数据,最坏的情况下需要 20 次查找。

根据平衡二叉树的特性,想要存储更多的数据,需要将树变深,变深之后会导致更多的I/O次数,影响效率;

如使用平横二叉树有如下弊端:

1、存储数据有限;

2、如存储过多数据,访问数据需要更多的I/O,影响效率;

B树

如下为数据结构

MySQL数据结构 (2).jpg

从数据结构上来看,对于平衡二叉树,B树每个节点能存储更多的数据。但B树的节点不仅存储键值,还存储数据。而innodb中页的默认大小是16K,存同样的数据,也会导致树的阶数(高度)增加。

如使用B树有弊端如下:

1、数据存储有限,查找数据磁盘I/O增多,数据查询效率变低;

2、对于范围查找、排序不适合;

B+树

B+树.jpg

对比B树以及其他数据结构,使用B+树有如下优势: 1、非叶子节点只存储索引,可以存储更多,且对比B树更矮胖,I/O次数更少; 2、叶子节点链式前后管理,方便范围查询;

索引分类

聚簇索引和非聚簇索引

按照主键值区分有两大分类:主键索引(聚簇索引)、非主键主键(非聚簇索引)

聚簇索引跟非聚簇索引的区别在于:聚簇索引的叶子节点存放主键值跟数据,非聚簇索引的叶子节点存放非主键索引以跟主键索引值

所以通过非聚簇索引查找的过程是先找到该索引Key对应的聚簇索引的Key,然后再拿聚簇索引Key到主键索引树上查找对应的数据,这个过程称为回表!

因此,DBA建议表在创建的时候需要指定主键值,没有主键的表是没有灵魂的。而如果不指定主键,MySQL也会默认生成一个主键值。

类型区分

按照索引类型区分有如下分类:

  • 唯一索引:Unique,唯一键
  • 普通索引:Normal
  • 全文索引:Full Text
  • 组合索引:联合索引,包含2个及以上列组成的索引

前面章节讲过,索引的结构是B+树,如有多个索引,就有多颗B+树;有多个索引的话,实际的数据只在主键索引那棵树存一份;

索引失效原因

对于使用了索引,但是没有生效的场景有如下原因:

  • 使用模糊查询:比如左模糊或者全模糊都会导致索引失效,比如'%肖'和'%肖%',但右模糊索引是有效的,比如'肖%';
  • 索引字段使用函数表达式:比如select name from user where substring(name,1,3)='abc';
  • 查询的时候索引包含表达式运算:比如select id from user where id/2=100;
  • 不满足联合索引最左前缀匹配:比如(A,B,C)的联合索引,where条件使用C或B或B,C都会失效;
  • 查询类型不匹配:比如age为varchar类型,查询语句为select name from user where age = 16,值没加引号;

索引调优

1、避免建立过多索引,多使用组合索引(单表索引不超过5个)

2、经常用于查询条件的字段建议加索引,通过索引查询,速度更快

3、频繁group by、order by的字段建议生成索引,可以大幅提高分组和排序效率

4、数据具有唯一性,建议生成唯一性索引,在数据库的层面,保证数据正确性

5、区分度较低的字段不建议加索引,比如性别字段(区分度超过30%,建议不加索引)

6、频繁更新的字段不建议加索引,重建索引时,会增加数据库的开销

7、尽量使用覆盖索引

索引知识点

回表

先通过数据库非主键索引扫描出数据所在的行,再通过行主键id取出索引中的数据,即基于非主键索引的查询需要多扫描一棵索引树;

索引覆盖

如果一个索引包含(或者说覆盖)所有需要查询的字段的值,不需要回表查询,我们就称之为索引覆盖;

最左匹配原则

对多个字段同时建立的组合索引(有顺序,abc、acb 是完全不同的两种联合索引)以联合索引(a,b,c)为例,建立这样的索引相当于建立了索引 a、ab、abc 三个索引。另外组合索引实际还是一个索引,并非真的创建了多个索引,只是产生的效果等价于产生多个索引;

索引下推

MySQL 5.6 引入了索引下推优化。可以在索引遍历过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,减少回表次数;


?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 14:04:31  更:2021-10-07 14:05:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 11:51:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码