MySQL存储过程拆表操作指南,如何高效拆分数据表并优化性能?

文章导读
以下是一个高效的MySQL存储过程拆表示例代码,用于根据日期字段拆分大表到分表中:
📋 目录
  1. 来源1
  2. 来源2
  3. 来源3
  4. 来源4
  5. 来源5
  6. 来源6
A A

以下是一个高效的MySQL存储过程拆表示例代码,用于根据日期字段拆分大表到分表中:

DELIMITER $$ CREATE PROCEDURE SplitTableByDate(IN table_name VARCHAR(64), IN date_column VARCHAR(32), IN split_date DATE) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE batch_size INT DEFAULT 10000; DECLARE cur CURSOR FOR SELECT id FROM table_name WHERE DATE(date_column) < split_date LIMIT batch_size; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN cur; read_loop: LOOP FETCH cur INTO @id; IF done THEN LEAVE read_loop; END IF; SET @sql = CONCAT('INSERT INTO ', table_name, '_split SELECT * FROM ', table_name, ' WHERE id = ', @id); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; DELETE FROM table_name WHERE id = @id; END LOOP; CLOSE cur; END$$ DELIMITER ; 这个过程每批次处理10000条记录,避免锁表时间过长。

来源1

在MySQL中,水平拆表(Sharding)是常见优化手段。通过存储过程自动化拆分:首先创建分表结构相同的新表,然后循环迁移数据,最后优化原表索引。关键是使用EXPLAIN分析查询计划,确保拆表后JOIN操作高效。实际案例中,一张10亿行日志表拆分为按月分表后,单表查询从30s降到0.5s。

来源2

高效拆表步骤:1. 分析表结构和数据分布,选定拆分键如user_id或create_time。2. 创建存储过程批量INSERT...SELECT并DELETE,避免事务过长。示例:CREATE PROCEDURE shard_user_table() BEGIN WHILE (SELECT COUNT(*) FROM users WHERE user_id % 10 = 0) > 0 DO INSERT INTO users_0 SELECT * FROM users WHERE user_id % 10 = 0; DELETE FROM users WHERE user_id % 10 = 0; COMMIT; END WHILE; END; 3. 分表后重建索引和统计信息:ANALYZE TABLE users_0;

来源3

性能优化tips:拆表时用pt-online-schema-change工具零停机,但存储过程适合自定义逻辑。监控拆分过程:SELECT TABLE_NAME, TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA='db'; 拆表比例控制在1:10,避免过多分表导致管理复杂。结合读写分离,写入主库分表,读从库聚合查询。

MySQL存储过程拆表操作指南,如何高效拆分数据表并优化性能?

来源4

按时间拆表存储过程完整版:DELIMITER // CREATE PROCEDURE partition_by_month(IN base_table VARCHAR(50)) BEGIN DECLARE month_suffix VARCHAR(7); SET month_suffix = DATE_FORMAT(NOW(), '%Y%m'); SET @ddl = CONCAT('CREATE TABLE ', base_table, '_', month_suffix, ' LIKE ', base_table); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET @insert_sql = CONCAT('INSERT INTO ', base_table, '_', month_suffix, ' SELECT * FROM ', base_table, ' WHERE DATE(create_time) >= ''', DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 MONTH), '%Y-%m-01'), ''''); PREPARE stmt FROM @insert_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END// 每月自动运行,提升INSERT速度30%。

来源5

拆表后性能测试:原表单表查询QPS 500,拆10表后QPS 4500。注意事项:分表键选择hash(user_id)避免热点;使用中间表暂存数据,减少锁竞争;拆分完成后DROP旧表或RENAME TABLE原子切换。

来源6

FAQ:
Q: 拆表会影响现有应用吗?
A: 如果用存储过程在线拆分,配合小批量事务,停机时间可控制在秒级。
Q: 如何选择拆分字段?
A: 选高基数、低倾斜的字段,如时间或用户ID,避免按性别等低选择性字段。
Q: 分表数量多少合适?
A: 单表建议控制在2000万行,视服务器内存调整,总分表数不超过1000。
Q: 拆表后查询怎么聚合?
A: 应用层UNION或中间件如MyCat自动路由。