为了拥有高性能的数据库,创建良好的表结构以及索引是必不可少的,与此同时对于表以及索引的维护也很重要
1 表的维护
1.1 检查并修复坏表
数据库表损坏的原因很多,操作系统问题,硬件问题,或者是手工的修改了MYSQL的数据文件,都会导致表的损坏。当出现问题时可能会导致查询行为的异常,具体的异常行为在不同版本的数据库中都不同。
当发现数据库的表行为有异常时,可以使用CHECK TABLE testable;(不是所有的数据库引擎都支持)来进行检查,当检测到异常时 可以使用REPAIR TABLE testable;(不是所有的数据库引擎都支持)来进行修复,如果存储殷勤不支持REPAIR Table,可以使用ALTER TABLE testableengine=INNODB的方式来进行修复。
下面以dictionary表为例,演示在INNODB中的操作(不支持REPAIR TABLE)
1.2 恢复丢失的数据
除了操作的失误(误删数据或表),当数据库的表出现异常时,也往往会伴随着数据的丢失。当悲剧发生时,除了想办法找到丢失的数据以外,还要找到出现数据丢失的根源
可以通过以下的两种方式来找回丢失的记录,不同存储引擎的恢复策略会不同
(1) 使用MySQL自带的工具集(http://dev.mysql.com/doc/refman/5.7/en/backup-and-recovery.html)
(2) 当第一种方法无效时,使用专业的工具集(Percona Data Recovery Tool for InnoDB:http://www.percona.com/software/mysql-innodb-data-recovery-tools)
2 索引的维护
在每个数据库的查询操作中,查询优化器会更具当前数据库的综合情况(例如,cache,index,表数据等)提供最优的执行计划。在MYSQL中,针对Index查询优化器会通过record_in_range()以及info()两个API 函数来了解存储引擎中索引的分布情况,从而决定如何使用索引。如果这两个函数返回的信息不足以让优化器来使用,查询优化器会根据“索引统计信息”来进行优化。
2.1 更新索引统计信息
当索引的统计信息也不准确时,可以通过执行 ANALYZE TABLE来重新索引统计信息。
索引的统计信息维护在存储引擎层实现,不同的存储引擎实现方式是不同的,下面以INNODB为例进行分析。
在MySQL 5.5 版本的InnoDB中,索引的统计信息没有存储在磁盘中,而是采取随机抽样索引页的方式进行分析,并且把抽样分析的结果放在内存中。老版本中会抽取8个索引页,在5.5以及更新的版本中可以通过innodb_stats_sample_pages参数来制定抽样的数量,可以通过http://dev.mysql.com/doc/innodb/1.1/en/innodb-other-changes-statistics-estimation.html来了解该参数的具体信息
当进行下列操作时,Innodb的索引统计信息会重新计算
· 首次打开表
· Analyzetable
· 表发生明显的大小变化(空间超过1/16或者是插入了20亿条记录)
当进行下列操作时,Innodb的索引统计信息会得到更新
· 打开某些information_schema表
· 执行show table status from testDB
· 执行show index form testable;
· 客户端开启了统计信息自动补齐功能
当数据库的数据量比较大时,频繁的执行索引统计新的的计算以及update是非常的消耗资源的,尤其是执行show table status操作时一定会触发更新动作,为了避免对性能产生影响,可以通过
SET GLOBALinnodb_stats_on_metadata=OFF
(or0
). 来解决该问题。
在其他的数据库产品中(Percona)还可以通过使用innodb_stats_auto_commit参数关掉索引统计信息自动更新的功能,或者是使用持久话的技术来维护索引统计信息。
2.2 清理索引以及表碎片
对与索引碎片,B-Tree索引会产生存储碎片,过多的碎片会对查询的性能造成很大的影响。
对于表碎片,InnoDB会产生行间碎片,和索引碎片一样,过多的表碎片也会对性能产生影响。
OPTIMIZETABLE 可以整理index以及表的碎片,但是只支持MyISAM,InnoDB, and ARCHIVE 。
由于InnoDB支持OPTIMIZE TABLE语法,所以可以使用以下的方式来对INNODB的表进行优化:
截图中出现的“Table does notsupport optimize, doing recreate + analyze instead”可以不用关注。
对于不支持OPTIMIZE TABLE语法的存储引擎,可以手工的通过(Drop/Crete Index+Alter tabletestable engine=…)的方式来清理碎片