首页 文章 精选 留言 我的

MySQL表碎片整理

1. OPTIMIZE TABLE 命令

这是最常用的碎片整理方法:

sql 复制代码
-- 基本用法
OPTIMIZE TABLE table_name;

-- 整理多个表
OPTIMIZE TABLE table1, table2, table3;

-- 实际示例
OPTIMIZE TABLE users, orders, products;

适用场景:

  • MyISAM、InnoDB、ARCHIVE 表
  • 表经过大量 DELETE、UPDATE 操作后
  • 需要回收空间并优化性能

2. ALTER TABLE 重建

sql 复制代码
-- 方法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 表

sql 复制代码
-- 使用 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 表

sql 复制代码
-- OPTIMIZE TABLE
OPTIMIZE TABLE myisam_table;

-- 或者使用 REPAIR TABLE
REPAIR TABLE myisam_table;

-- 带选项的修复
REPAIR TABLE myisam_table QUICK;

4. 批量整理脚本

sql 复制代码
-- 整理所有表的存储过程
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. 命令行工具

bash 复制代码
# 使用 mysqlcheck 工具
mysqlcheck -o database_name table_name
mysqlcheck -o database_name  # 整理整个数据库

# 整理所有数据库
mysqlcheck -o --all-databases

# 带连接参数
mysqlcheck -o -u username -p database_name

6. 自动化脚本(Shell)

bash 复制代码
#!/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. 检查碎片程度

在整理前先检查碎片情况:

sql 复制代码
-- 查看表碎片情况
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;

注意事项

  1. 锁表问题:OPTIMIZE TABLE 会锁表,建议在业务低峰期执行
  2. 磁盘空间:需要额外的磁盘空间来完成操作
  3. InnoDB 注意事项
    • OPTIMIZE TABLE 在 InnoDB 中会被映射为 ALTER TABLE
    • 使用 innodb_file_per_table 可以更好地管理空间
  4. 备份:重要操作前建议备份数据
  5. 复制环境:在主从复制环境中,OPTIMIZE TABLE 会被复制到从库

最佳实践

  • 定期监控表碎片情况
  • 在低峰期执行整理操作
  • 对于大表,考虑分批次整理
  • 使用 pt-online-schema-change 工具进行在线表重构

选择合适的方法取决于你的具体需求、表的大小和业务影响程度。

优秀的个人博客,低调大师

微信关注我们

本文章为原创内容,如需转载请注明来源!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

MySQL数据库中FOR UPDATE的使用

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...

相关文章

发表评论

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。