索引的作用

索引是用来高效的获取数据的 排好序数据结构,如果没有索引,可能会导致查询某一条记录的时候遍历整张表;所以适当的索引可以大大的提升检索速度;

索引的数据结构

  • 二叉树

假如说我们有一列数据是0-6,我们使用的是二叉树进行存储的话,此时我们可以看到二叉树的存储方式为下图:

  • 我们可以看到二叉树如同链表的形式存储了完整的数据,这时我们假设要查值为6的数据,我们就需要七次IO操作才能拿到数据结果;试想假如我们数据过多这时候查询数据就会非常的慢,就相当于全表扫描;
  • 所以我们的mysql数据库,肯定是不会用这种数据结构来存储数据;
  • 红黑树

  • 同样是的存储数据0-6,这时我们会发现红黑树在每次存储的时候,都会动一下;目的就是为了平衡,本质上和二叉树是一样的这里只是多了一步平衡操作,所以红黑树又称平衡二叉树
  • 在查询上我们也可以看到,相比于二叉树来说它做了平衡,树层级相对来说会变小,在我们查找数据的时候IO操作也相对来说少些了;
  • mysql也没用这种数据结构,其实我们也应该想的到,一方面数据多了节点一直往下分散还是可能会很多;另一个方面每变动一个节点的时候树都会做平衡花销不可估量;
  • hash表

hash 我们知道查找数据的复杂度为O(1)

  • 对索引的key进行一次hash计算就可以定位出数据的存储位置;
  • 很多时候hsah比b+tree更高效,因为只要hash到对应的key值就能拿到元素;
  • 只能满足 "=", "in" 不能范围查找;
  • 会存在hash冲突问题(如上图key=2的数据,同一个key存储了两个值,在拿数据的时候会定位到2的数据,然后一次比对拿符合条件的数据);

    因为本质的复杂度为O(1)特性速度一般会很快,但是我们工作中一般用的不是很多,最根本也是最重要的原因是不支持范围查找,还存在hash冲突的问题;
  • b-tree
  • 通过上边你的二叉树红黑树我们可以发现都有个共同的问题,就是数据多了层级都会很深查数据都会很慢;这里b-tree就做了一个改进,每个节点可以横向扩展存更多的数据,这时树的层级就会明显变少,减少磁盘IO操作;如下图:

  • 上图我们可以看到,节点横向扩展可以存储更多的节点数据, 也就是说一次IO操作我们可以那倒更多的数据,如果不存在时我们就进行下一个节点查询; 我们也可以看到每个索引元素都同时存储了data数据, 也就是说当我们找到索引是可以马上拿到data的; 节点中的数据索引从左到右依次递增;
  • mysql也不是用的这种数据结构,毕竟还是存在一些弊端如:
  1. 每个索引节点都存储了data数据,每个节点的存储空间有限,这时层级也会存在深的情况;
  2. 没有相邻的双向指针,当范围查找时都需要节点挨个筛选,不利于范围查询;
  3. 当我们发生修改删除数据时,也会伴随着树节点的变动,从而造成性能上的损耗;
  • b+tree

mysql用的就是这种数据结构, 其实b+tree是b-tree的一个变种大概还是一样做了些改进:

  1. 非叶子节点不存储data数据, 只存储索引,相比于b-tree可以放更多的索引;
  2. 叶子节点存有data和所有节点的索引字段;
  3. 叶子节点之间用指针相连接,提升了区间访问的性能;
  4. 节点中的索引从左到右依次递增;
  5. 删除数据时只删除叶子节点,非叶子节点不变,不影响整个树的结构;

补充 树中每个节点可以存储16Kb的数据

可以用下方sql查询

show GLOBAL STATUS like 'Innodb_page_size'

那我们来计算下每个节点大概能存储多少数据:

假设我们用bigInt类型当自增主键的话,bigInt也就是上图的索引元素占8个字节,磁盘地址指针mysql默认分配6个字节;也就是说我们一个节点可以存储16Kb/(8+6)B约等于1170个元素;叶子节点因为要存储data元素所以元素个数可能会相对其他节点少,我们假设只存储了15个元素,那么我们一个三阶的树就可以存储 1170117015 约 两千万条数据,也就是说两千万的数据我们只需要三次IO就能拿到值(mysql本身也有做优化非叶子节点会被加载到内存中,也就是说我们取值可能就一次IO就能拿到值,速度会大大提升);

MyISAM 存储引擎

MyISAM 存储引擎中数据存储分三个文件存储分别为 .frm结构 .MYD数据 .MYI索引 三个文件,即为非聚集索引



上图我们可以看到索引和数据存在不同的文件中,当我们检索数据的时候是先找MYI文件定位到引用地址,再去MYD中拿数据的;

InnoDB 存储引擎

InnoDB 存储引擎中数据和索引是放在同一个文件中分别为 .frm结构 .idb 两个文件,即为 聚集索引

  • InnoDB 中每个叶子节点存储整条数据的所有字段(如叶子节点索引18,存储的是数据 77 Alice);
  • 表文件本身就是一个b+tree树组织的索引结构文件;
  • 由于主键和数据都在同一个文件中,所以InnoDB必须要有一个主键,并且建议为自增主键(如果不设主键则mysql会自动的在你的列表中找到一个符合条件的唯一索引字段,如果没有mysql将添加一个类似 ROW_Id 充当主键);
  • 非主键索引结构的叶子节点存储的是主键值,是为了实现一致性,节省存储空间;
聚集索引和非聚集索引哪个效率更高

非聚集索引查询到索引值之后,只是拿到了索引所在行的磁盘文件地址,需要通过这个地址再进行一次I/O操作;

聚集索引读取到叶子节点索引值之后,即那到了索引所在行的完整的数据内容,不需要额外的I/O操作;

工具辅助

动图树模拟地址:https://www.cs.usfca.edu/~galles/visualization/BST.html;

动图制作工具:GifCam工具

mysql总结笔记 -- 索引篇的更多相关文章

  1. 数据库MySQL学习笔记高级篇

    数据库MySQL学习笔记高级篇 写在前面 学习链接:数据库 MySQL 视频教程全集 1. mysql的架构介绍 mysql简介 概述 高级Mysql 完整的mysql优化需要很深的功底,大公司甚至有 ...

  2. mysql优化之索引篇

    对mysql优化是一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引.主键索引.唯一索引unique.全文索引] c: 分表技术(水平 ...

  3. Mysql学习笔记—索引

    一.什么是索引 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 在数据 ...

  4. MySQL学习笔记Windows篇<一> Welcome to MySQL

    MySQL安装完毕后没有图形化操作界面,图形化管理界面需要另行安装,个人比较喜欢Navicat,界面更像SQLserver: 此篇学习笔记所有操作均使用命令行中完成: 1.开启/停止服务 使用MySQ ...

  5. MySQL学习笔记——索引和视图

    索引(index)和管理索引 模式中的一个数据库对象 作用:在数据库中用来加速对表的查询 创建:自动在主键和唯一键上面创建索引 通过使用快速路径访问方法快速定位数据,减少了磁盘的I/O 与表独立存放, ...

  6. 【笔记】MySQL学习之索引

    [笔记]MySQL学习之索引 一 索引简单介绍 索引,是数据库中专门用于帮助用户快速查询数据的一种数据结构.类似于字典中的目录,查找字典内容时可以根据目录查找到数据的存放位置,然后直接获取即可. 普通 ...

  7. mysql那些事之索引篇

    mysql那些事之索引篇 上一篇博客已经简单从广的方面介绍了一下mysql整体架构以及物理结构的内容. 本篇博客的内容是mysql的索引,索引无论是在面试还是我们日常工作中都是非常的重要一环. 索引是 ...

  8. 精通MySQL之索引篇,这篇注重练习!

    老刘是即将找工作的研究生,自学大数据开发,一路走来,感慨颇深,网上大数据的资料良莠不齐,于是想写一份详细的大数据开发指南.这份指南把大数据的[基础知识][框架分析][源码理解]都用自己的话描述出来,让 ...

  9. Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)

    转自:Mysql数据库优化技术之配置篇.索引篇 ( 必看 必看 ) (一)减少数据库访问对于可以静态化的页面,尽可能静态化对一个动态页面中可以静态的局部,采用静态化部分数据可以生成XML,或者文本文件 ...

随机推荐

  1. Markdown随时记录

    Markdown学习 推荐文本编译器 Typora 标题(支持六级) 一级标题:# + 空格 + 内容 二级标题:## + 空格 + 内容 三级标题:### + 空格 + 内容 . . . 字体 粗体 ...

  2. Sentinel之流控规则

    在上文Sentinel流量防卫兵中讲到了Sentinel入门以及流控规则一小部分,而Sentinel还有以下规则: 熔断降级规则 热点参数规则 系统规则 黑白名单规则 本文要讲的是流控规则 流量控制规 ...

  3. 设计风格之REST

    一.简介 REST简介 REST 是英文 representational state transfer(表象性状态转变)或者表述性状态转 移;Rest 是 web 服务的一种架构风格;使用 HTTP ...

  4. Linux下安装中文字体

    目录 一.Centos系列 二.Ubuntu系列 一.Centos系列 1.安装字体库 yum -y install fontconfig 2.添加中文字体,建立存储中文字体的文件夹 mkdir /u ...

  5. Python连接MySQL数据库获取数据绘制柱状图

    一.Python通过pymysql包获取MySQL数据库中的数据(没有对应包的可以通过pip install pymysql 安装对应的包) import matplotlib.pyplot as p ...

  6. vue双向绑定和深浅拷贝

    现象描述: vue 在使用的时候,当table绑定了某个data的时候.假如某个el-table-column下面的有个方法传参(data.row),然后在方法中用一个obj=data.row.(这里 ...

  7. 数据类型Table.TransformColumnTypes(Power Query 之 M 语言)

    数据源: 任意数据源 目标: 设置适合的数据类型 操作过程: 选取指定列>[主页]>[数据类型]>选取 选取指定列>[转换]>[数据类型]>选取 选取指定列> ...

  8. CF938B Run For Your Prize 题解

    Content 有两个人,一个在 \(1\) 处,一个在 \(10^6\) 处,在他们之间有 \(n\) 个奖品,第 \(i\) 个奖品在 \(a_i\) 处.一开始在 \(1\) 处的人每秒可向右移 ...

  9. java IO操作和计算操作:工作内存和主内存 volatile关键字作用;原子操作对象AtomicInteger ....

    应该停止但无法停止的计算线程 如下线程示例,线程实例中while循环中的条件,在主线程中通过调用实例方法更新后,while循环并没有更新判断变量是否还成立.而是陷入了while(true)死循环. i ...

  10. 金山云 KS3 Python SDK 多线程并发上传文件;下载断点续传 参考脚本

    并发上传 基于py自带模块 concurrent.futures import ThreadPoolExecutor #!/usr/bin/env python3 # -*- coding:utf-8 ...