当前位置: 主页 > Office办公 > 电脑专区 > 电脑教程 > MySQL 数据库碎片优化、整理方法详细步骤图解教程

MySQL 数据库碎片优化、整理方法详细步骤图解教程

  • 2021-11-21
  • 来源/作者: 菜鸟图库/ 菜鸟图库
  • 453 次浏览

起因:查看线上数据库中Table Information时发现有一个日志表数据大小和索引大小有915M,但实际行数只有92行。该表需要频繁插入并且会定时去删掉旧的记录。表类型为Myisam,已建立一个索引,所以应该是产生了大量碎片,使用 Optimize table 表名 优化后大小变为2.19M,少了很多, 同时可以看出该表上的索引建的多余,因为插入操作比查询操作要多很多,而且查询不多,查询的数据量也一般比较小。

MySQL 数据库碎片优化、整理方法详细步骤图解教程

借此延伸下MYSQL中Myisam、InnoDB碎片优化方式:

Myisam清理碎片
OPTIMIZE TABLE table_name

InnoDB碎片优化
if you frequently delete rows (or update rows with variable-length data types), you can end up with a lot of wasted space in your data file(s), similar to filesystem fragmentation.

If you’re not using the innodb_file_per_table option, the only thing you can do about it is export and import the database, a time-and-disk-intensive procedure.

But if you are using innodb_file_per_table, you can identify and reclaim this space!

Prior to 5.1.21, the free space counter is available from the table_comment column of information_schema.tables. Here is some SQL to identify tables with at least 100M (actually 97.65M) of free space:

SELECT table_schema, table_name, table_comment FROM information_schema.tables WHERE engine LIKE ‘InnoDB’ AND table_comment RLIKE ‘InnoDB free: ([0-9]{6,}).*‘;

Starting with 5.1.21, this was moved to the data_free column (a much more appropriate place):

SELECT table_schema, table_name, data_free/1024/1024 AS data_free_MB FROM information_schema.tables WHERE engine LIKE ‘InnoDB’ AND data_free > 100*1024*1024;

You can reclaim the lost space by rebuilding the table. The best way to do this is using ‘alter table’ without actually changing anything:

ALTER TABLE foo ENGINE=InnoDB;

This is what MySQL does behind the scenes if you run ‘optimize table’ on an InnoDB table. It will result in a read lock, but not a full table lock. How long it takes is completely dependent on the amount of data in the table (but not the size of the data file). If you have a table with a high volume of deletes or updates, you may want to run this monthly, or even weekly.

什么是mysql碎片?怎样知道表的碎片有多大呢?
简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不同,这种是数据碎片.实际上数据碎片分为两种,一种是单行数据碎片,另一种是多行数据碎片.前者的意思就是一行数据,被分成N个片段,存储在N个位置.后者的就是多行数据并未按照逻辑上的顺序排列.当有大量的删除和插入操作时,必然会产生很多未使用的空白空间,这些空间就是多出来的额外空间.索引也是文件数据,所以也会产生索引碎片,理由同上,大概就是顺序紊乱的问题.Engine 不同,OPTIMIZE 的操作也不一样的,MyISAM 因为索引和数据是分开的,所以 OPTIMIZE 可以整理数据文件,并重排索引.

OPTIMIZE 操作会暂时锁住表,而且数据量越大,耗费的时间也越长,它毕竟不是简单查询操作.所以把 Optimize 命令放在程序中是不妥当的,不管设置的命中率多低,当访问量增大的时候,整体命中率也会上升,这样肯定会对程序的运行效率造成很大影响.比较好的方式就是做个 Script,定期检查mysql中 information_schema.TABLES字段,查看 DATA_FREE 字段,大于0话,就表示有碎片.脚本多长时间运行一次,可以根据实际情况来定,比如每周跑一次.

我们在使用MySQL的时候,每当我们从表中删除一个数据的时候,都会让这段空间滞空。如果在短时间内删除大量的数据,那么这些留出来的空间比数据库中保留的数据所使用的空间还要大。虽然在mysql插入新的数据时候,mysql会尽最大的可能使用这些空间,但是依然是无法全部重新利用的,所以学会mysql碎片清理是很有用处的

mysql> select table_schema, table_name, data_free, engine     from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;

 
+--------------+-----------------------+-----------+--------+
| table_schema | table_name            | data_free | engine |
+--------------+-----------------------+-----------+--------+
| BK           | comments              |   9437184 | InnoDB |
| BK           | historypwd            |   9437184 | InnoDB |
| ss | app_admin_log         |        434 | MyISAM |
| ss | app_article           |        4434 | MyISAM |
|ss | app_article_category  |        43420 | MyISAM |
| ss | app_config            |        3324 | MyISAM |
| ss | app_convert_key       |       1132 | MyISAM |
 
如上图所示中,data_free是指碎片的空间。
你可以通过这两条语句对数据库进行碎片清理:
 
Optimize table ss.app_article;     //这种方式只支持MyIsam引擎
 
INNODB使用    ALTER  TABLE  table.name EMGINE=’InnoDB’;   //使用之前最好对数据备份
 
学会数据库碎片的处理可以大大的增加数据库利用的空间,现在很多的空间上都限定mysql的数据空间大小,如果超过的话需要加收费用,所以使用碎片处理可以减少费用的支出。

标签(TAG) MySQL数据库