1.什么是索引

官方定义:一种能为mysql提高查询效率的数据结构,索引是为了加速对表中数据行的检索而创建的一种分散存储的数据结构。好比如,一本书,你想找到自己想看的章节内容,直接查询目录就行。这里的目录就类似索引的意思。

1.1索引的工作原理

如上图中,如果现在有一条sql语句 select * from user where id = 40,如果没有索引的条件下,我们要找到这条记录,我们就需要在数据中进行全表扫描,匹配id = 40的数据。

如果有了索引,我们就可以通过索引进行快速查找,如上图中,可以先在索引中通过id = 40进行二分查找,再根据定位到的地址取出对应的行数据。

现在看来,索引是不是也不过如此。咋们接着往下看。

索引的优点:
1.大大加快数据的查询速度。
索引的缺点:
1.维护索引需要耗费数据库资源。
2.索引需要占用磁盘空间
3.当对表的数据增删改的时候,因为要维护索引,速度会受到影响。</pre>

那么有的同学可能会问,既然索引缺点这么多,那我为什么还要用索引啊?也就是提高了查询速度而已。

提高了查询速度呀,这个绝对是个大优势,在数据量庞大的情况下,我们通过命中索引,能大大的提高查询速度,增删改基本消耗忽略不计。摘抄阿里P3C开发规范。

2.索引的分类

1.主键索引
设定为主键后,数据库会自动为其创建主键索引,innodb为聚簇索引。
2.普通索引:用表中的普通列构建的索引,没有任何限制,用于加速查询。
3.组合索引:用多个列组合构建的索引,这多个列中的值不允许有空值。
4.全文索引(mysql5.7之前,由MyISAM提供):用大文本对象的列构建的索引,主要用来查找文件中的关键字。

3.B+Tree

我们先来看一个sql

image

执行完后:

奇怪?为什么数据和我插入的顺序不一致呢,竟然给我自动排序好了!!!我们接着看

其实mysql每条数据的存储是这样子的(图自己画的,—_—,将就下)

每次插入数据的时候,mysql会给我们自己排序好,因为这样可以快速的查询数据。并且会通过P的指针链接到下一条数据。这里看起来是不是像某种数据结构?链表的数据结构,对了,就是这样。
疑问点???
我们都知道链表查询数据的时间复杂度为On,那么当数据量一多的话,我要查的id特别大呢,这和全表扫描有什么区别呢?接着往下看。

mysql给我们提供了页的概念,并且有页目录,页目录数据为叶族节点每页的第一条数据id,页目录和每页大小均默认为16KB,如下图:

举个例子:

那么这个时候假如我想要查询id 为2的这条数据,在页目录中,2在1~4之间,直接去到第一页,查询第一页第一条数据为1,因为有指针P的存在,那么就可以顺着指针往下找即可。即找到了2。此时呢只进行了一次IO操作。现在想想看,是不是查询速度快很多。P指针的概念也很强大,是不是。

那么有的小伙伴可能会问,你这样也存不了多少数据呀,那假如我数据量非常多呢,这颗数怎么存呢。
以上表而言,一个id占用8个字节(long类型),name 20个字节,p指针也要占用字节的(大概4~8个字节),我们以最大8来算,那么一条数据大概就是:8+20+8=36,36个字节,那么一页换算一下是 16x1024 = 16384 个字节,那么叶子节点一页可以存储数据量为:16384/36 = 455 条数据。那么页目录又存着id,一个id8个字节,能存储16x1024/8 =2048,2048x455 = 931,840 …粗略的算了下3层数,能存储数据量为1,908,408,320个 很多了,可能表的字段很多的话,存储数据量稍微少点,但是也很多了。

3.对比B-Tree

可以看到b-Tree上的每个节点都存储了数据,那么,我们刚刚说了,mysql一页的大小为16KB,那么这样的话,一页能存储的数据就很少了,因为数据要占用每页的字节呀。这样树的深度可能就深了。我们知道mysql每次读取数据时会进行一次IO操作,那么深度越深,IO的次数不是会越多。说白了优化优化,大多数都是在IO层做优化的。那么对比B+Tree,数据只存在叶子节点上,树的深度就不是那么深了(一般企业级不会超过3层深度)

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。

我们来总结下B+Tree和B-Tree的区别

1.B+Tree非叶子结点只存储键值信息。
2.B+Tree所有叶子节点都有一个指针(上面说到了指针的用途)。
3.B+Tree数据都存储在叶子节点上,B-Tree节点上都存储数据。innoDB存储引擎页大小为16KB,一般主键类型为INT(占用4个字节)或BIGINT(占用8个字节)。

这个时候有个问题思考下?为什么mysql推荐ID自增呢?这个时候是不是心里有了答案呢?或许自己可以先想想再看。

在InnoDB的实践里面其中一个建议是按主键的自增顺序插入记 录,就是为了避免Page Split问题。比如一个Page里依次装入了Key为(1,3,5,9)四条记录,并且假设这个Page满了。接下来如果插入一个 Key =4的记录,就不得不建一个新的Page,同时把(1,3,5,9)分成两半,前一半(1,3,4)还在旧的Page中,后一半(5,9)拷贝到新的Page 里,并且要调整Page前后的双向链表的指针关系,这显然会影响插入速 度。但如果插入的是Key = 10的记录,就不需要做Page Split,只需要建 一个新的Page,把Key = 10的记录放进去,然后让整个链表的最后一个 Page指向这个新的Page即可。
另外一个点,如果只是插入而不硬删除记录(只是软删除),也会 避免某个Page的记录数减少进而发生相邻的Page合并的问题。

3.聚簇索引和非聚簇索引

聚簇索引:将数据与索引放到了一块,索引的叶子节点保存了行数据。
非聚簇索引:将数据分开存储,索引结构的叶子节点指向了数据对应的位置。
总结:InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分;

我们日常工作中,根据实际情况自行添加的索引都是辅助索引,辅助索引就是一个为了需找主键索引的二级索引,现在找到主键索引再通过主键索引找数据;(这就是所谓的回表查询)

聚簇索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的就是整张表的行记录数据,也将聚集索引的叶子节点称为数据页。这个特性决定了索引组织表中数据也是索引的一部分,每张表只能拥有一个聚簇索引。

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。具体细节依赖于其实现方式。

聚簇索引的优缺点

优点:

1.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快

2.聚簇索引对于主键的排序查找和范围查找速度非常快   缺点:

1.插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键     2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。    3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

辅助索引(非聚簇索引)

聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找。辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的Page Directory找到数据行。

总之,其实说白了也就是,我们平常定义的索引就是辅助索引,平常通过普通索引查询数据时,先通过辅助索引查询到主键索引,再通过主键索引查询到具体的数据。

彻底搞懂MySql的B+Tree相关推荐

  1. 一文搞懂 MySQL 索引

    一文搞懂 MySQL 索引 1.MySQL 索引 简介 1.1.MySQL 索引 是什么?  索引是一个单独的.存储在 磁盘 上的 数据库结构 ,包含着对数据表里 所有记录的 引用指针. 1.2. M ...

  2. 学习最新大厂付费视频时整理的万字长文+配图带你搞懂 MySQL

    万字长文+配图带你搞懂 MySQL MySQL SQL的介绍 SQL分类 MySQL语法 创建数据库 修改.删除.使用数据库 DDL查询数据表 DDL创建数据表 修改数据表结构 删除数据表 DML添加 ...

  3. mysql decimal型转化为float_5分钟搞懂MySQL数据类型之数值型DECIMAL类型

    速成指南 5分钟搞懂MySQL数据类型 之数值型--DECIMAL类型 DECIMAL类型的语法:DECIMAL[(M[,D])] [UNSIGNED] [ZEROFILL].其中M指定的是数字的总位 ...

  4. 图文结合带你搞懂MySQL日志之Error Log(错误日志)

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 作者:KAiTO 文章来源:社区原创 往期回顾: 图 ...

  5. 丁奇mysql45讲百度云下载_MySQL实战45讲,丁奇带你搞懂MySQL【完结】

    开篇词.这一次,让我们一起来搞懂MySQL.mp3 开篇词.这一次,让我们一起来搞懂MySQL.pdf 01.基础架构:一条SQL查询语句是如何执行的?.mp3 01.基础架构:一条SQL查询语句是如 ...

  6. mysql 什么树_搞懂MySQL InnoDB B+树索引

    一.InnoDB索引 InnoDB支持以下几种索引: B+树索引 全文索引 哈希索引 本文将着重介绍B+树索引.其他两个全文索引和哈希索引只是做简单介绍一笔带过. 哈希索引是自适应的,也就是说这个不能 ...

  7. 一文搞懂MySQL数据库分库分表

    如果数据量过大,大家一般会分库分表.分库需要注意的内容比较少,但分表需要注意的内容就多了. 工作这几年没遇过数据量特别大的业务,那些过亿的数据,因为索引设置合理,单表性能没有影响,所以实战中一直没用过 ...

  8. 一文搞懂MySQL XA如何实现分布式事务

    一文搞懂MySQL XA如何实现分布式事务 前言 XA 协议 如何通过MySQL XA实现分布式事务 前言 MySQL支持单机事务的良好表现毋庸置疑,那么在分布式系统中,涉及多个节点,MySQL又是如 ...

  9. 通俗易懂地搞懂决策树(Decision Tree)那些事儿

    一.决策树是什么? "决策树是一颗好树,是一颗可以帮我们做决策的树." 决策树的结构:树形结构,节点表示判断条件(分为根节点和中间节点),分支代表判断结果,叶子代表分类结果. 二. ...

最新文章

  1. 【高并发】高并发场景下如何优化加锁方式?看完这篇我确实明白了!!
  2. R语言爬取imdb电影海报
  3. 【图数据库】史上超全面的Neo4j使用指南
  4. Python中的数值类型
  5. 《leetcode》longest-substring-without-repeating
  6. Java——集合框架(List)
  7. 实时事理逻辑知识库(事理图谱)终身学习项目-EventKGNELL(学迹)
  8. CAN笔记(18) 对象字典
  9. 8266不通过usb供电_HomePod mini?电源线同样不可拆卸:但或能用USB-C移动电源供电...
  10. 数据结构思维 翻译完成
  11. 蓝桥杯2015年第六届C/C++B组第六题-加法变乘法
  12. 关于《Delphi源代码分析》的讨论
  13. java获取系统所有字体_java获取本机所有可用字体
  14. Linux gerp 命令使用方法
  15. Python练习题答案: 杰克的家【难度:2级】--景越Python编程实例训练营,1000道上机题等你来挑战
  16. 2014腾讯校招面试之二总结
  17. 传输层 SACK与选择性重传算法
  18. 电子词典中鼠标取词的原理
  19. 内网服务器安装docker
  20. SQL Server 2014 的完美卸载

热门文章

  1. 基于Java的多元化智能选课系统 毕业设计-附源码040909
  2. 塞拉利昂一公司计划投资10亿美元用于建设光伏农业项目
  3. [C语言]统计成绩问题:输入某班学生某门课的成绩(最多不超过40人,具体人数由用户键盘输入),用函数编程统计不及格人数。
  4. 【C/C++基础进阶系列】实战记录 -- Dump 文件生成与分析
  5. 《CSS揭秘》-总结47个Css技巧(一):常用的背景与边框技巧
  6. Springsecurity+cas整合后无法单点登出
  7. X86_64 GNU汇编、寄存器、内嵌汇编
  8. 一文带你盘点市场上主流的BI产品主要有哪些
  9. win7系统安装telnet服务器,Win7怎样安装telnet服务?
  10. Sprite Kit 移动精灵