[转]聚簇索引与非聚簇索引(也叫二级索引)

2023-10-28

通俗点讲

  • 聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据
  • 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因

澄清一个概念:innodb中,在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值

何时使用聚簇索引与非聚簇索引

cluster.png

聚簇索引具有唯一性

由于聚簇索引是将数据跟索引结构放到一块,因此一个表仅有一个聚簇索引

一个误区:把主键自动设为聚簇索引

聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引。InnoDB 只聚集在同一个页面中的记录。包含相邻健值的页面可能相距甚远。如果你已经设置了主键为聚簇索引,必须先删除主键,然后添加我们想要的聚簇索引,最后恢复设置主键即可

此时其他索引只能被定义为非聚簇索引。这个是最大的误区。有的主键还是无意义的自动增量字段,那样的话Clustered index对效率的帮助,完全被浪费了。

刚才说到了,聚簇索引性能最好而且具有唯一性,所以非常珍贵,必须慎重设置。一般要根据这个表最常用的SQL查询方式来进行选择,某个字段作为聚簇索引,或组合聚簇索引,这个要看实际情况。

记住我们的最终目的就是在相同结果集情况下,尽可能减少逻辑IO

结合图再仔细点看

image

image

  1. InnoDB使用的是聚簇索引,将主键组织到一棵B+树中,而行数据就储存在叶子节点上,若使用"where id = 14"这样的条件查找主键,则按照B+树的检索算法即可查找到对应的叶节点,之后获得行数据
  2. 对Name列进行条件搜索,则需要两个步骤第一步在辅助索引B+树中检索Name,到达其叶子节点获取对应的主键。第二步使用主键在主索引B+树种再执行一次B+树检索操作,最终到达叶子节点即可获取整行数据。(重点在于通过其他键需要建立辅助索引

MyISM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树

聚簇索引的优势

看上去聚簇索引的效率明显要低于非聚簇索引,因为每次使用辅助索引检索都要经过两次B+树查找,这不是多此一举吗?聚簇索引的优势在哪?

  1. 由于行数据和叶子节点存储在一起,同一页中会有多条行数据,访问同一数据页不同行记录时,已经把页加载到了Buffer中,再次访问的时候,会在内存中完成访问,不必访问磁盘。这样主键和行数据是一起被载入内存的,找到叶子节点就可以立刻将行数据返回了,如果按照主键Id来组织数据,获得数据更快
  2. 辅助索引使用主键作为"指针"而不是使用地址值作为指针的好处是,减少了当出现行移动或者数据页分裂时辅助索引的维护工作使用主键值当作指针会让辅助索引占用更多的空间,换来的好处是InnoDB在移动行时无须更新辅助索引中的这个"指针"也就是说行的位置(实现中通过16K的Page来定位)会随着数据库里数据的修改而发生变化(前面的B+树节点分裂以及Page的分裂),使用聚簇索引就可以保证不管这个主键B+树的节点如何变化,辅助索引树都不受影响
  3. 聚簇索引适合用在排序的场合,非聚簇索引不适合
  4. 取出一定范围数据的时候,使用用聚簇索引
  5. 二级索引需要两次索引查找,而不是一次才能取到数据,因为存储引擎第一次需要通过二级索引找到索引的叶子节点,从而找到数据的主键,然后在聚簇索引中用主键再次查找索引,再找到数据
  6. 可以把相关数据保存在一起。例如实现电子邮箱时,可以根据用户 ID 来聚集数据,这样只需要从磁盘读取少数的数据页就能获取某个用户的全部邮件。如果没有使用聚簇索引,则每封邮件都可能导致一次磁盘 I/O。

聚簇索引的劣势

  1. 维护索引很昂贵,特别是插入新行或者主键被更新导至要分页(page split)的时候。建议在大量插入新行后,选在负载较低的时间段,通过OPTIMIZE TABLE优化表,因为必须被移动的行数据可能造成碎片。使用独享表空间可以弱化碎片
  2. 表因为使用UUId(随机ID)作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更慢,

image

所以建议使用int的auto_increment作为主键

image

主键的值是顺序的,所以 InnoDB 把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB 默认的最大填充因子是页大小的 15/16,留出部分空间用于以后修改),下一条记录就会写入新的页中。一旦数据按照这种顺序的方式加载,主键页就会近似于被顺序的记录填满(二级索引页可能是不一样的)

  1. 如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值;过长的主键值,会导致非叶子节点占用占用更多的物理空间

为什么主键通常建议使用自增id

聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。如果主键不是自增id,那么可以想 象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作,但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。

因为MyISAM的主索引并非聚簇索引,那么他的数据的物理地址必然是凌乱的,拿到这些物理地址,按照合适的算法进行I/O读取,于是开始不停的寻道不停的旋转聚簇索引则只需一次I/O。(强烈的对比)

不过,如果涉及到大数据量的排序、全表扫描、count之类的操作的话,还是MyISAM占优势些,因为索引所占空间小,这些操作是需要在内存中完成的

mysql中聚簇索引的设定

聚簇索引默认是主键,如果表中没有定义主键,InnoDB 会选择一个唯一的非空索引代替。如果没有这样的索引,InnoDB 会隐式定义一个主键来作为聚簇索引。InnoDB 只聚集在同一个页面中的记录。包含相邻健值的页面可能相距甚远



作者:kindol
链接:https://www.jianshu.com/p/fa8192853184
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转]聚簇索引与非聚簇索引(也叫二级索引) 的相关文章

随机推荐

  • C语言的员工管理系统

    include
  • Mac操作系统下 命令行 cp命令的坑

    Mac系统下的命令与Linux系统下的命令大部分是一样的 但是有一些事不同的用法 有的时候找个命令在Linux下好使 在Mac下就不好使 下面来研究下cp命令在Mac系统下的坑 Mac MacBook Pro mac mkdir aa Ma
  • Your build is currently configured to use Java 17.0.6 and Gradle 5.6.4.

    报错信息 Unsupported Java Your build is currently configured to use Java 17 0 6 and Gradle 5 6 4 Possible solution Upgrade G
  • C++ abort() has been called错误

    程序可以成功编译 说明没有语法问题 应是代码内部的问题 报错如下 abort has been called 中止被调用 该错误出现有很多原因 查询了多条博客后 发现一卒2018博主已经在博客上总结了几条原因和解决办法 谢谢博主 借博主的思
  • JAVA容器学习-集合

    Java集合是我认为在Java基础中最最重要的知识点了 Java集合是必须掌握的 我在实习 秋招面试的时候 只要是面到Java 那一定是少不了Java集合 作为一个新人 最关心的其实有一点 这个技术在工作中是怎么用的 换个说法 工作中常用到
  • 如何在BIOS中开启虚拟化技术

    虚拟化技术目前主要依赖于您电脑的CPU型号及BIOS 某些CPU或者BIOS暂时还不能支持虚拟化技术 支持虚拟化技术的可以在BIOS中开启 开启方法如下 1 进入BIOS 开机时按F2或F12或DEL或ESC等键 各电脑有所不同 2 进入B
  • jmeter安装和压力测试

    一 安装 1 1 下载安装包 1 2 解压到指定目录 1 3 配置环境变量 JMETER HOME D java apache jmeter 5 1 1 CLASSPATH JMETER HOME lib ext ApacheJMeter
  • React利用路由实现登录界面的跳转

    React利用路由实现登录界面的跳转 上一篇在配置好了webpack和react的环境后 接下来开始写登录界面 以及接下来的跳转到主页的功能 1 首先看一下总体的目录结构 因为很多时候在看别人写的例子的时候因为目录结构不熟悉后边会出现意想不
  • Android RecyclerView BaseSectionQuickAdapter实现分组功能

    详情网站 手把手教你使用BaseSectionQuickAdapter实现分组功能 史上最详细Adapter使用教程 basequickadapter 分组 杨阿程的博客 CSDN博客 加入二个包 implementation com an
  • Python 文件读取操作

    视频版教程 Python3零基础7天入门实战视频教程 文件IO操作 Python的内置库提供了对文件的IO操作 可以对文件进行打开 读 写 关闭等操作 文件读取操作 你必须先用Python内置的open 函数打开一个文件 创建一个file对
  • 软件工程 数据流图(DFD)变换型与事务型的分析

    在系统分析阶段 我们采用结构化分析方法得到了由数据流图 数据字典和加工说明等组成的系统的逻辑模型 现在 可根据一些规则从数据流图导出系统初始的模块结构图 管理信息系统的数据流图通常也可分为两种典型的结构 即变换型结构和事务型结构 变换型结构
  • 10-Java框架-SpringBoot整合MyBatis-Plus

    一 MyBatis Plus介绍 官网 https baomidou com MyBatis Plus 简称 MP 是一个 MyBatis的增强工具 在 MyBatis 的基础上只做增强不做改变 无侵入式 为简化开发 提高效率而生 MyBa
  • H5 打开微信小程序 公众号

    1 打开公众号的方式 https mp weixin qq com mp profile ext action home biz 公众号BASE64ID scene 110 wechat redirect base64ID 寻找方式 转发任
  • 基于 SpringBoot+Vue+Java 的高校招生管理系统(数据库+源码和教程)

    文章目录 简介 系统设计思路 1 数据库设计 2 系统整体设计 2 1 系统设计思想 2 2系统流程图 系统详细设计 1系统功能模块 2 管理员功能模块 3学生功能模块 简介 本次设计任务是要设计一个高校招生管理系统 通过这个系统能够满足管
  • [python应用案例] 一.BeautifulSoup爬取天气信息并发送至QQ邮箱

    前面作者写了很多Python系列文章 包括 Python基础知识系列 Python基础知识学习与提升 Python网络爬虫系列 Python爬虫之Selenium Phantomjs CasperJS Python数据分析系列 知识图谱 w
  • 【sqli-labs】 less29 GET- Error based -Impidence mismatch -Having a WAF in front of web application (G...

    这关有点意思 有一点需要事先注意 这关玩的是login php而不是默认的index php 再注入之前需要先了解一下HPP HTTP Parameter Pollution 详情参照这篇 http blog csdn net eatmil
  • caffe:利用python分类,并可视化模型参数、数据

    caffe官方文档 http nbviewer jupyter org github BVLC caffe blob master examples 00 classification ipynb 1准备工作 1 1 安装python nu
  • 通过ffmpeg进行录屏直播

    1 在Windows上安装FFmpeg程序 转载 参考地址 https www cnblogs com daxiong2014 p 4399046 html 2 通过ffmpeg进行录屏直播 参考地址 https blog csdn net
  • shopify cli 的命令

    shopify theme 多语言国际化开发 shopify theme 跨境电商开发 liquid 本地编辑shopify主题的方式一 shopify cli 的命令 使用shopify help
  • [转]聚簇索引与非聚簇索引(也叫二级索引)

    通俗点讲 聚簇索引 将数据存储与索引放到了一块 找到索引也就找到了数据 非聚簇索引 将数据存储于索引分开结构 索引结构的叶子节点指向了数据的对应行 myisam通过key buffer把索引先缓存到内存中 当需要访问数据时 通过索引访问数据