碎片
mysql查询包括根据一级索引查询和二级索引查询,一级索引可以根据主键进行查询,为了避免行间碎片化和页的分裂,一般主键列为自增长的类型。查询一般按照业务逻辑索引进行查询,这就是二级索引查询。会根据索引查到对应条件的主键,根据查询到的主键再定位到具体的数据
mysql数据访问的瓶颈在于io访问,对于顺序访问能够提高io的访问速度,对于随机访问硬盘io的速度就会慢很多
碎片主要有两种,索引的碎片化和数据存储的碎片化
B-tree需要随机的磁盘访问才能定位到叶子页,所以如果叶子节点在物理分布上是顺序且紧密的,那么查询的效果会比较好,否则对于范围查询和索引覆盖扫描来说,速度会降低很多
索引碎片化
B+ Tree索引碎片化,这会降低查询的效率,碎片化的索引可能会以很差或者无序的方式存储在硬盘上。
数据存储碎片化
数据存储碎片化主要包括三种,行碎片化,行间碎片,剩余空间碎片
行碎片
这种碎片化是因为一行数据太长,一页存储不下,导致数据存在两个页中,这样一行数据访问把两个page读取到内存中,无疑增加了io访问延迟。这种解决办法是一般将数据的基本信息存在一个表中,将数据的拓展信息另行存储。比如一个user的基本信息存储在user表中,而用户的其他关系另行存储,这样有利于将一个用户的信息存储在一个页中。
行间碎片
对于行间碎片,是因为对于实际逻辑相邻的两行实际上在物理逻辑上不是连续的。这一般是因为对数据的不断删除和插入导致的,对于查询一定范围的数据,在逻辑上应该是连续的,但是对于数据使用过程中不断删除和插入导入的页分裂和数据的重新存储,
剩余空间碎片
剩余空间碎片是由于对于一个page调用,而这个page中不是所有的size都存储着数据,导致一个page调用查询的结果只能得到较少的结果。
解决
对于发生碎片的表可以采用两种方法解决 OPTIMIZE TABLE,对于不支持OPTIMIZE TABLE的engine来说可以使用,alter table <table> engine=<engine>;
B-tree需要随机的磁盘访问才能定位到叶子页,所以如果叶子节点在物理分布上是顺序且紧密的,那么查询的效果会比较好,否则对于范围查询和索引覆盖扫描来说,速度会降低很多
对于索引的碎片化,可以通过删除索引和重建索引来解决