ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
B-Tree索引可能会碎片化,这会降低查询效率.碎片化的索引可能会以很差或者无序的方式存储在磁盘上 根据设计B-Tree需要随机磁盘访问才能定位到叶子页,所以随机访问是不可避免的.然而,如果叶子页在物理分布上是顺序且紧密的,那么查询性能就会更好.否则,对于范围查询,索引覆盖扫描等操作来说,速度可能会降低很多倍,对于索引覆盖扫描这一点更加明显 表的数据存储也可能碎片化.然而,数据存储的碎片化比索引更加复杂.有三种类型的数据碎片 * 行碎片 这种碎片指的是数据被存储为多个地方的多个片段中.即使查询只从索引中访问一行记录,行碎片也会导致性能下降 * 行间碎片 行间碎片是值逻辑上顺序的页,或者行在磁盘上不是顺序存储的.行间碎片对诸如全表扫描和聚簇索引扫描之类的操作有很大的影响,因为这些操作原本能够从磁盘上顺序存储的数据中获益 * 剩余空间碎片 剩余空间碎片是指数据页中有大量的空余空间,这会导致服务器读取大量大需要的数据,从而造成浪费 对于myisam表,这三类碎片化都可能发生.但Innodb不会出现短小的行碎片,innodb会移动短小的行并重写到一个片段中 可以通过执行OPTIMIZE TABLE或者导出再导入的方式来重新整理数据,这对多数存储引擎都是有效的.对于一些存储引擎如myisam,可以通过排序算法重建索引的方式来消除水平.老版本的Innodb没有什么消除碎片化的方法.不过最新版本Innodb新增了"在线"添加和删除索引的功能,可以通过先删除,然后再重新创建索引的方式来消除索引的碎片化 对于那些不支持OPTIMIZE TABLE的存储引擎,可以通过一个不做任何操作的ALTER TABLE操作来重建表.只需要将表的存储引擎改为当前的引擎即可: ~~~ mysql> ALTER TABLE <table> ENGINE=<engine>; ~~~ 对于开启了`expand_fast_index_creation` 参数的Percona Server,按这种方式重建表,则会同时消除表和索引的碎片化.但对于标准版本的mysql则只会消除表(实际上是聚簇索引)的碎片化.可用先删除所有索引,然后重建表,最后重新创建索引的方式模拟Percona Server的这个功能