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

通俗点讲

  • 聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据
  • 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,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 只聚集在同一个页面中的记录。包含相邻健值的页面可能相距甚远。

posted on 2019-07-26 10:27 shoshana~ 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/shoshana-kong/p/11248711.html

聚簇索引与非聚簇索引(也叫二级索引)相关推荐

  1. 浅析聚簇索引与非聚簇索引(也叫二级索引)

    通俗点讲 聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内 ...

  2. MySQL聚簇索引和非聚簇索引(二级索引) B+树 数据页(索引页)

    对于Inndb来说,判断是否是聚簇索引,看B+树是否存放完整的数据就行. 对于MyISAM来说,全部都是非聚簇索引,即二级索引.因为它的所有和树是分开的. 注意:下面都是针对InnoDB 聚簇索引:所 ...

  3. 聚簇索引mysql语句_mysql索引之聚簇索引与非聚簇索引

    1 数据结构及算法基础 1.1 索引的本质 官方定义:索引(Index)是帮助MySQL高效获取数据的数据结构 本质:索引是数据结构 查询是数据库的最主要功能之一.我们都希望查询速度能尽可能快,因此数 ...

  4. 聚簇索引、非聚簇索引、普通索引、唯一索引

    一.聚簇索引 VS 非聚簇索引 聚簇索引:将数据存储与索引放到了一块,找到索引也就找到了数据 非聚簇索引:将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buf ...

  5. mysql 聚簇索引和非聚簇索引_图文并茂,说说MySQL索引

    点击上方 小伟后端笔记 ,选择 星标 公众号 重磅资讯.干货,第一时间送达 作者:小小木的博客来源:cnblogs.com/wyc1994666/p/10831039.html 序 开门见山,直接上图 ...

  6. mysql 聚簇_mysql索引总结(3)-MySQL聚簇索引和非聚簇索引

    非聚簇索引 索引节点的叶子页面就好比一片叶子.叶子头便是索引键值. 先创建一张表: CREATE TABLE `user` ( `id`INT NOT NULL, `name`VARCHAR NOT ...

  7. MySQL中的聚簇索引、非聚簇索引、联合索引和唯一索引

    一.索引类型 索引根据底层实现可分为B-Tree索引和哈希索引,大部分时候我们使用的都是B-Tree索引,因为它良好的性能和特性更适合于构建高并发系统. 根据索引的存储方式来划分,索引可以分为聚簇索引 ...

  8. 稀疏索引、密集索引、聚簇索引、非聚簇索引

    密集索引 可以理解为是一种树形结构,其每个叶子节点对应的值都是唯一的,并且每个节点只有一个值. 稀疏索引 同样可以理解为是一种树形结构,但是其叶子节点对应的值可以是一个列表,并且列表的值是可重复的. ...

  9. MySQL索引:聚簇索引和非聚簇索引的区别

    目录 1.聚簇索引和非聚簇索引的概念 2.两者详细介绍 2.1 聚簇索引 2.2 非聚簇索引 3. 两者的区别 3.1 数据存储方式 3.2 二级索引查询 1.聚簇索引和非聚簇索引的概念 数据库表的索 ...

最新文章

  1. jQuery 设置select默认选中问题
  2. 华为nova5ipro的优缺点_华为nova5pro和nova5i的区别
  3. 一加3t刷机后还卡_OPPO A5?A7?A57?刷机注意:这几款手机千万别混淆!
  4. 编程python爬取网页数据教程_实例讲解Python爬取网页数据
  5. crawler_x-requested-with 请求头
  6. Spring boot 中pom.xml 各个节点详解
  7. Beacon Mountain 测试版 – 常见问题解答
  8. 修改Hosts不生效的解决办法
  9. Windows 10图标如何调整?
  10. 翻译学习 | 混合线性模型的思考
  11. 使用PCtoLCD2002字模提取软件
  12. beego 静态文件处理
  13. 数字化经济时代的企业信息化管理转型——数据化 信息化 数字化 智慧管理的概念及它们之间的关系
  14. springboot+shiro+nutz+beetl + mysql
  15. linux tig不支持中文,解决git log 以及tig命令中文乱码问题
  16. 下一代CDN如何与智能AI及物联网打通?
  17. 限速之令牌桶和漏桶算法
  18. 与计算机和网络有关的英语,网络的英语作文(通用10篇)
  19. 网站TDK的设置方法-怎么合理的设置网站的TDK
  20. 一、H5全景图-朋友圈全景图-720°全景-VR -----工具使用

热门文章

  1. Visual Studio2022 生成可执行文件
  2. 百度商桥接入客服指南!
  3. 树梅派迅雷远程下载服务器搭建
  4. Java学习_Day 18(学习内容:尚硅谷IO流JAVA零基础P598-P612)
  5. 海洋气象数据可视化,以流场的方式显示风场图,海洋气象API使用
  6. oracle19c静默创建实例,Oracle 19C dbca silent 静默建库
  7. AD9361的Rx增益控制(一)增益控制的阈值检测器
  8. VCT的日常操作流程及注意事项
  9. ec200s 方案 移远_电动车充电桩无线通信方案移远4GCAT1全网通无线通信模组EC200S...
  10. 中国移动ML302模组(4G Cat.1 通信模组)TencentOS-tiny AT模组框架适配