[MySQL] 5.索引(三)——聚簇索引

时间:2019-10-09
本文章向大家介绍[MySQL] 5.索引(三)——聚簇索引,主要包括[MySQL] 5.索引(三)——聚簇索引使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

聚簇索引

聚簇索引是一种数据存储方式,InnoDB的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行。当表有聚簇索引时,它的数据行实际上存放在索引的叶子页中(叶子页包含了行的全部数据,节点页只包含了索引列)。“聚簇”表示数据行和相邻的键值紧凑的存储在一起。一个表只能有一个聚簇索引。

InnoDB会选择主键列进行聚簇索引,如果没有定义主键,InnoDB会选择唯一的非空索引代替。如果还是没有,InnoDB会隐式定义一个主键来作为聚簇索引。InnoDB只聚集在同一个页面中的记录。

InnoDb的普通索引(二级索引)的叶子结点中存放的是主键的值,所以需要先查询普通索引(二级索引)的叶子节点找到对应的主键值,然后再根据主键值去聚集索引中查询到对应的数据。

非聚集索引的索引与数据是存在不同文件的。

聚簇索引优点:

  • 可以把相关的数据保存在一起,例如实现电子邮箱时,可以根据用户ID来聚集数据,这样只需要从磁盘读取少数数据页就能获取某个用户的全部邮件,减少磁盘I/O次数。
  • 数据访问更快:聚簇索引同时将索引和数据保存在同一个B-Tree中,因此从聚簇索引中获取数据要比非聚簇索引更快。
  • 使用覆盖索引扫描的查询可以直接使用节点中的主键值。

聚簇索引缺点:

  • 聚簇索引最大限度地提高了I/O密集型应用的性能。如果数据全放放在内存中,那么聚簇索引就没了优势。
  • 插入速度严重依赖于插入顺序。按照主键顺序插入最快。
  • 更新聚簇索引列的代价很高,因为会强制InnoDB将每个被更新的行移动到新的位置。
  • 基于聚簇索引的表在插入新行,或者主键被更新导致需要移动行的时候,可能面临“页分裂”问题。当行的主键值要求必须将这一行插入到某个已满的页中时,存储引擎会将该页分裂成两个页面来容纳改行,这就是一次页分裂操作。页分裂会导致表占用更多磁盘空间
  • 当行比较稀疏,或者有由于页分裂导致数据存储不连续的时候,可能会导致全表扫描变慢。
  • 二级索引(费聚簇索引)可能比想象的要更大,因为在二级索引的叶子节点包含了引用行的主键列。
  • 二级索引访问需要两次索引查找,而不是一次(因为二级索引叶子节点保存的不是指向行的物理位置的指针,而是行的主键值)。

InnoDB和MyISAM数据分布对比

对于以下这个表,InnoDB和MyISAM存储方式不同:

1
2
3
4
5
6
7
CREATE TABLE layout_test (
col1 int NOT NULL,
col2 int NOT NULL,
PRIMARY KEY(col1),
KEY(col2)

);

MyISAM的数据分布

MyISAM按照数据插入的顺序存储在磁盘上,如图所示。因为这里行是定长的,所以MyISAM可以从表的开头跳过所需字节直接找到需要的行。可以看出MyISAM的主键索引和其他索引在结构上没有不同。

InnoDB的数据分布

如图所示,可以发现图中显示了整个表,而不仅仅是索引。因为在InnoDB中,聚簇索引就是表,不需要像MyISAM那样需要独立的行存储。

聚簇索引的每一个叶子结点都包含了主键值、事务ID、用于事务和MVCC的回滚指针以及所有的剩余列(在这里是col2)。如果主键是一个列前缀索引,InnoDB也会包含完整的主键列和剩下的其他列。

另一点和MyISAM不同的是,InnoDB的二级索引和聚簇索引并不相同。InnoDB二级索引的叶子节点中存储的不是“行指针”,而是主键值,并以此作为指向行的“指针”。这样会减少当出现行移动或者数据页分裂(上文有提到)时二级索引的维护工作。使用主键值当作指针会让二级索引占用更多的空间,换来的好处是,InnoDB在移动时无需更新二级索引中的这个“指针”。


在InnoDB表中按主键顺序插入行

尽量按主键顺序插入行,最简单的方法使用自增列(AUTO_INCREMENT)。因为这样填充时,当页满时,下一条记录就可以写在新页中。而如果无序插入,那么每次都要为行找到合适的位置,会增加许多额外工作。有以下一些缺点

  • 写入的目标页可能已经刷新到磁盘上,并从缓存中移除,InnoDB在插入前必须先找到并从磁盘读取目标页到内存中,导致大量随机I/O。
  • 因为写入是乱序的,InnoDB不得不频繁地做页分裂操作,以便为新的行分配空间。页分裂会导致移动大量数据,一次插入最少需要修改三个页,而不是一个页。
  • 频繁的页分裂,页会变得稀疏并被不规则地填充,最终会有碎片。

对于高并发工作负载,按主键顺序可能导致性能下降。

1
参考内容 >> 高性能MySQL第三版
----------- 本文结束,感谢阅读 -----------

原文:大专栏  [MySQL] 5.索引(三)——聚簇索引


原文地址:https://www.cnblogs.com/wangziqiang123/p/11642325.html