MySQL表碎片整理
1. OPTIMIZE TABLE 命令
这是最常用的碎片整理方法:
-- 基本用法
OPTIMIZE TABLE table_name;
-- 整理多个表
OPTIMIZE TABLE table1, table2, table3;
-- 实际示例
OPTIMIZE TABLE users, orders, products;
适用场景:
- MyISAM、InnoDB、ARCHIVE 表
- 表经过大量 DELETE、UPDATE 操作后
- 需要回收空间并优化性能
2. ALTER TABLE 重建
-- 方法1:简单重建
ALTER TABLE table_name ENGINE=InnoDB;
-- 方法2:带字符集重建(保持原字符集)
ALTER TABLE table_name ENGINE=InnoDB CHARACTER SET utf8mb4;
-- 实际示例
ALTER TABLE large_table ENGINE=InnoDB;
3. 针对不同存储引擎的方法
InnoDB 表
-- 使用 OPTIMIZE TABLE(推荐)
OPTIMIZE TABLE innodb_table;
-- 或者使用 ALTER TABLE
ALTER TABLE innodb_table FORCE;
-- 在线 DDL(MySQL 5.6+)
ALTER TABLE innodb_table ALGORITHM=INPLACE, LOCK=NONE;
MyISAM 表
-- OPTIMIZE TABLE
OPTIMIZE TABLE myisam_table;
-- 或者使用 REPAIR TABLE
REPAIR TABLE myisam_table;
-- 带选项的修复
REPAIR TABLE myisam_table QUICK;
4. 批量整理脚本
-- 整理所有表的存储过程
DELIMITER $$
CREATE PROCEDURE optimize_all_tables()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE tbl_name VARCHAR(255);
DECLARE cur CURSOR FOR
SELECT table_name
FROM information_schema.tables
WHERE table_schema = DATABASE()
AND table_type = 'BASE TABLE';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO tbl_name;
IF done THEN
LEAVE read_loop;
END IF;
SET @sql = CONCAT('OPTIMIZE TABLE `', tbl_name, '`');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;
-- 调用存储过程
CALL optimize_all_tables();
5. 命令行工具
# 使用 mysqlcheck 工具
mysqlcheck -o database_name table_name
mysqlcheck -o database_name # 整理整个数据库
# 整理所有数据库
mysqlcheck -o --all-databases
# 带连接参数
mysqlcheck -o -u username -p database_name
6. 自动化脚本(Shell)
#!/bin/bash
# 数据库连接信息
DB_HOST="localhost"
DB_USER="username"
DB_PASS="password"
DB_NAME="database_name"
# 整理单个数据库
mysqlcheck -h $DB_HOST -u $DB_USER -p$DB_PASS -o $DB_NAME
# 或者整理特定表
mysql -h $DB_HOST -u $DB_USER -p$DB_PASS -e "OPTIMIZE TABLE table1, table2;" $DB_NAME
7. 检查碎片程度
在整理前先检查碎片情况:
-- 查看表碎片情况
SELECT
TABLE_NAME,
ENGINE,
TABLE_ROWS,
DATA_LENGTH,
INDEX_LENGTH,
DATA_FREE,
ROUND(DATA_FREE/(DATA_LENGTH+INDEX_LENGTH)*100, 2) AS fragment_percent
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_database'
AND DATA_FREE > 0
ORDER BY fragment_percent DESC;
注意事项
- 锁表问题:OPTIMIZE TABLE 会锁表,建议在业务低峰期执行
- 磁盘空间:需要额外的磁盘空间来完成操作
- InnoDB 注意事项:
- OPTIMIZE TABLE 在 InnoDB 中会被映射为 ALTER TABLE
- 使用
innodb_file_per_table可以更好地管理空间
- 备份:重要操作前建议备份数据
- 复制环境:在主从复制环境中,OPTIMIZE TABLE 会被复制到从库
最佳实践
- 定期监控表碎片情况
- 在低峰期执行整理操作
- 对于大表,考虑分批次整理
- 使用
pt-online-schema-change工具进行在线表重构
选择合适的方法取决于你的具体需求、表的大小和业务影响程度。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Crontab安装和使用
安装crontab sh 复制代码 # 安装crontab yum install cronie -y 常用命令 如果使用service则使用下列命令 sh 复制代码 # 启动 service crond start # 停止 service crond stop # 重启 service crond restart # 运行状态 service crond status # 重新载入配置 service crond reload 如果使用systemctl则使用下列命令 sh 复制代码 # 启动 systemctl start crond # 停止 systemctl stop crond ...
-
下一篇
MySQL数据库中FOR UPDATE的使用
在MySQL中,FOR UPDATE是一个非常重要的锁机制,主要用于在事务中锁定查询到的数据行,防止其他事务修改这些数据。 基本语法 sql 复制代码 SELECT * FROM table_name WHERE condition FOR UPDATE; 主要作用 1. 行级排他锁 对查询结果集加排他锁(X锁) 其他事务无法对这些行加任何锁,包括读锁和写锁 其他事务可以普通读取(取决于隔离级别),但不能修改 2. 防止数据竞争 在并发环境下,防止多个事务同时修改同一数据: sql 复制代码 -- 事务1 START TRANSACTION; SELECT balance FROM accou...
相关文章
文章评论
共有0条评论来说两句吧...

微信收款码
支付宝收款码