简单聊一下对MySQL索引的理解?
一、索引是什么?
索引是帮助MySQL高效获取数据的数据结构。
二、索引能干什么?
索引非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。 索引能够轻易将查询性能提高好几个数量级,总的来说就是可以明显的提高查询效率。
三、索引的分类?
1、从存储结构上来划分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。这里所描述的是索引存储时保存的形式,
2、从应用层次来分:普通索引,唯一索引,复合索引
3、根据中数据的物理顺序与键值的逻辑(索引)顺序关系:聚集索引,非聚集索引。
平时讲的索引类型一般是指在应用层次的划分。
就像手机分类:安卓手机,IOS手机 与 华为手机,苹果手机,OPPO手机一样。
普通索引:即一个索引只包含单个列,一个表可以有多个单列索引
唯一索引:索引列的值必须唯一,但允许有空值
复合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
聚簇索引(聚集索引):并不是一种单独的索引类型,而是一种数据存储方式。具体细节取决于不同的实现,InnoDB的聚簇索引其实就是在同一个结构中保存了B-Tree索引(技术上来说是B+Tree)和数据行。
非聚簇索引:不是聚簇索引,就是非聚簇索引
四、索引的底层实现
mysql默认存储引擎innodb只显式支持B-Tree( 从技术上来说是B+Tree)索引,对于频繁访问的表,innodb会透明建立自适应hash索引,即在B树索引基础上建立hash索引,可以显著提高查找效率,对于客户端是透明的,不可控制的,隐式的。
Hash索引
基于哈希表实现,只有精确匹配索引所有列的查询才有效,对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),并且Hash索引将所有的哈希码存储在索引中,同时在索引表中保存指向每个数据行的指针。
B-Tree索引(MySQL使用B+Tree)
B-Tree能加快数据的访问速度,因为存储引擎不再需要进行全表扫描来获取数据,数据分布在各个节点之中。
B+Tree索引
是B-Tree的改进版本,同时也是数据库索引索引所采用的存储结构。数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都指向相邻的叶子节点的地址。相比B-Tree来说,进行范围查找时只需要查找两个节点,进行遍历即可。而B-Tree需要获取所有节点,相比之下B+Tree效率更高。
案例:假设有一张学生表,id为主键
id | name | birthday |
---|---|---|
1 | Tom | 1996-01-01 |
2 | Jann | 1996-01-04 |
3 | Ray | 1996-01-08 |
4 | Michael | 1996-01-10 |
5 | Jack | 1996-01-13 |
6 | Steven | 1996-01-23 |
7 | Lily | 1996-01-25 |
在MyISAM引擎中的实现(二级索引也是这样实现的)
在InnoDB中的实现
五、为什么索引结构默认使用B+Tree,而不是Hash,二叉树,红黑树?
B-tree:因为B树不管叶子节点还是非叶子节点,都会保存数据,这样导致在非叶子节点中能保存的指针数量变少(有些资料也称为扇出),指针少的情况下要保存大量数据,只能增加树的高度,导致IO操作变多,查询性能变低;
Hash:虽然可以快速定位,但是没有顺序,IO复杂度高。
二叉树:树的高度不均匀,不能自平衡,查找效率跟数据有关(树的高度),并且IO代价高。
红黑树:树的高度随着数据量增加而增加,IO代价高。
六、为什么官方建议使用自增长主键作为索引?
结合B+Tree的特点,自增主键是连续的,在插入过程中尽量减少页分裂,即使要进行页分裂,也只会分裂很少一部分。并且能减少数据的移动,每次插入都是插入到最后。总之就是减少分裂和移动的频率。
插入连续的数据:
插入非连续的数据
七、简单总结下
1、MySQL使用B+Tree作为索引数据结构。
2、B+Tree在新增数据时,会根据索引指定列的值对旧的B+Tree做调整。
3、从物理存储结构上说,B-Tree和B+Tree都以页(4K)来划分节点的大小,但是由于B+Tree中中间节点不存储数据,因此B+Tree能够在同样大小的节点中,存储更多的key,提高查找效率。
4、影响MySQL查找性能的主要还是磁盘IO次数,大部分是磁头移动到指定磁道的时间花费。
5、MyISAM存储引擎下索引和数据存储是分离的,InnoDB索引和数据存储在一起。
6、InnoDB存储引擎下索引的实现,(辅助索引)全部是依赖于主索引建立的(辅助索引中叶子结点存储的并不是数据的地址,还是主索引的值,因此,所有依赖于辅助索引的都是先根据辅助索引查到主索引,再根据主索引查数据的地址)。
7、由于InnoDB索引的特性,因此如果主索引不是自增的(id作主键),那么每次插入新的数据,都很可能对B+Tree的主索引进行重整,影响性能。因此,尽量以自增id作为InnoDB的主索引。
文章转自https://mp.weixin.qq.com/s/gNmWY8ob-QN6ZVF7e-71cA,微信公众号-程序员的私房菜
简单聊一下对MySQL索引的理解?的更多相关文章
- Mysql索引深入理解
一. 引言 Mysql 我们平常用的很多,了解的很多,今天别的不说,直接说mysql的底层是什么,说到底层,就想到数据结构,那么,mysql的数据结构是什么呢? 是B + tree .那么数据库中的 ...
- 面试官:小伙子,你给我说一下你对MySQL索引的理解吧
一.索引是什么? 索引是帮助MySQL高效获取数据的数据结构. 二.索引能干什么? 索引非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要.索引能够轻易将查询性能提高好几个数量级,总 ...
- mysql索引相关理解
1.索引是高效获取数据的数据结构, 2.唯一索引,索引值不重复unique create unique index 索引名 on 表名(字段) alter table 表名 add unique in ...
- MySQL 索引最佳实践
原文请关注 这里 这是 文章 的翻译,在翻译过程中,会对其中涉及到的语句加上一些个人理解以及 SQL 语句的执行,并进行特别的标注. 1. 你做了一个很棒的选择,因为: 对于普通开发者和 DBA,理解 ...
- 深入浅出Mysql索引优化专题分享|面试怪圈
文章纲要 该文章结合18张手绘图例,21个SQL经典案例.近10000字,将Mysql索引优化经验予以总结,你可以根据纲要来决定是否继续阅读,完成这篇文章大概需要25-30分钟,相信你的坚持是不负时光 ...
- [译] MYSQL索引最佳实践
近日整理文档时发现多年前的这个文档还是蛮实用的,然后在网络搜索了一下并没有相关的译文,所以决定把它翻译过来,如有不当的地方请多包涵和指正.原文地址:https://www.percona.com/fi ...
- 理解MySQL——索引与优化
转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...
- mysql创建索引以及对索引的理解
创建表的时候创建索引 创建索引是指在某个表的一列或多列上建立一个索引,以便提高对表的访问速度.创建索引有3种方式,这3种方式分别是创建表的时候创建索引.在已经存在的表上创建索引和使用ALTER T ...
- 【转】mysql索引最左匹配原则的理解
作者:沈杰 链接:https://www.zhihu.com/question/36996520/answer/93256153 来源:知乎 CREATE TABLE `student` ( `id` ...
随机推荐
- java多线程中篇(二) —— 线程的创建和Synchronized锁关键字
学习之前,先了解线程状态图 说明:线程共包括以下5种状态. 1. 新建状态(New) : 线程对象被创建后,就进入了新建状态.例如,Thread thread = new Thread ...
- (一)linux 学习 -- 在文件系统中跳转
The Linux Command Line 读书笔记 - 部分内容来自 http://billie66.github.io/TLCL/book/chap03.html 文章目录 文件系统 根目录 打 ...
- oracle安装内核参数设置
安装oracle内核参数说明及设置 kernel.shmmax 说明: Linux进程可以分配的单独共享内存段的最大值(byte) 64位的linux操作系统,设置应该大于SGA_MAX_TARGET ...
- ~request库的使用
官方文档: (中文)http://cn.python-requests.org/zh_CN/latest/ (英文)https://2.python-requests.org//en/master/a ...
- go语言实现链式栈
haa哈哈== import "errors" var ( // ErrEmpty 栈为空 ErrEmpty = errors.New("stack is empty&q ...
- GitHub的Fork是什么意思
GitHub的Fork 是什么意思[转] GitHub Help Simple guide to forks in GitHub and Git GitHub的Fork 是什么意思-N神3-博客园 G ...
- Python之特征工程-3
一.什么是特征工程?其实也是数据处理的一种方式,和前面的原始数据不一样的是,我们在原始数据的基础上面,通过提取有效特征,来预测目标值.而想要更好的去得出结果,包括前面使用的数据处理中数据特征提取,新增 ...
- 二、openfeign生成并调用客户端动态代理对象
所有文章 https://www.cnblogs.com/lay2017/p/11908715.html 正文 上一篇文章中,我们了解到了@FeignClient注解的接口被扫描到以后,会生成一个Fe ...
- UI5-技术篇-Expand与Deep 服务测试
1.SEGW创建服务 2.创建Data Model 2.1Entity Types ZRICO_USR 设置主键.排序字段.过滤字段 ZRICO_USRITM设置主键 2.2Associations ...
- Qt定时器
PS: 本案例使用的是Qt 4.8.4版本,不同版本代码可能会有差异. 第一步: // 重写此虚函数(继承自QObject) virtual void timerEvent(QTimerEvent* ...