维护索引和表
维护表有三个主要目的:
找到并修复损坏的表
维护准确的索引统计信息
减少碎片
找到并修复损坏的表
损坏的索引会导致查询返回错误的结果或者出现莫须有的主键冲突等问题,严重时甚至还会导致数据库的崩溃。如果你遇到了古怪的问题——例如一些不应该发生的错误——可以尝试运行 CHECK TABLE 来检查是否发生了表损坏。CHECK TABLE 通常能够找出大多数的表和索引的错误。
可以使用 REPAIR TABLE 命令来修复损坏的表,但同样不是所有的存储引擎都支持该命令。如果存储引擎不支持,可通过一个不做任何操作(no-op)的 ALTER 操作来重建表,例如,将表的存储引擎修改为当前的引擎。
更新索引统计信息
如果存储引擎向优化器提供的扫描行数信息不准确,或者执行计划本身太复杂以致无法准确地获取各个阶段匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。
MySQL 的优化器使用的是基于成本的模型,而衡量成本的主要指标就是一个查询需要扫描多少行。如果表没有统计信息,或者统计信息不准确,优化器就很有可能做出错误的决定。可以通过运行 ANALYZE TABLE 来重新生成统计信息,以解决这个问题。
减少索引和数据的碎片
B-tree 索引可能会产生碎片化,这会降低查询的效率。碎片化的索引可能会以很差或者无序的方式存储在磁盘上。
根据设计,B-tree 索引需要随机磁盘访问才能定位到叶子页,所以随机访问总是不可避免的。然而,如果叶子页在物理分布上是顺序且紧密的,那么查询的性能就会更好。否则,对于范围查询、索引覆盖扫描等操作来说,速度可能会降低很多;对于索引覆盖扫描,这一点会表现得更加明显。
表的数据存储也可能发生碎片化,数据存储的碎片化比索引更加复杂。有三种类型的数据碎片:
行碎片(Row fragmentation) 这种碎片指的是数据行被存储在多个地方的多个片段中,即使查询只从索引中访问一行记录,行碎片也会导致性能下降。
行间碎片(Intra-row fragmentation) 行间碎片是指逻辑上顺序的页或者行,在磁盘上不是顺序存储的。行间碎片对诸如全表扫描和聚簇索引扫描之类的操作有很大的影响,因为这些操作原本能够从磁盘上顺序存储的数据中获益。
剩余空间碎片(Free space fragmentation) 剩余空间碎片是指数据页中有大量的空余空间。这会导致服务器读取大量不需要的数据,从而造成浪费。
可以通过执行 OPTIMIZE TABLE 或者导出再导入的方式来重新整理数据。这对多数存储引擎都是有效的。对于那些不支持 OPTIMIZE TABLE 的存储引擎,可以通过一个不做任何操作(no-op)的 ALTER TABLE 操作来重建表。只需将表的存储引擎修改为当前的引擎即可:
最后更新于