壓測、基準測試、新功能驗證常需千萬級測試數據。本文揭示「存儲過程批量提交 + 臨時切換 MyISAM 引擎」組合拳,將 1500 萬條插入從小時級壓縮至分鐘級,並給出演練腳本、引擎切換風險控制、數據驗證清單。
| 技術點 | InnoDB 默認行為 | 優化後行為 | 加速倍數 |
|---|---|---|---|
| 事務提交 | 每條 INSERT 隱式提交(自動提交) | 每 1000 條手動 COMMIT | ~1000x 減少 fsync |
| 存儲引擎 | InnoDB (雙寫緩衝、REDO/UNDO 日誌、MVCC) | MyISAM (無事務、無日誌、順序寫入) | ~5-10x 寫入吞吐 |
| 索引維護 | 聚簇索引 + 二級索引實時維護 | 僅非聚簇索引,批量構建 | ~2-3x |
-- 1. 目標表(預建結構,無索引/僅主鍵)
CREATE TABLE `test` (
`id` INT NOT NULL AUTO_INCREMENT,
`code` VARCHAR(20) DEFAULT 'sdfasdfas',
`name` VARCHAR(20) DEFAULT 'aaa',
PRIMARY KEY (`id`)
) ENGINE=InnoDB; -- 初始用 InnoDB 便於後續業務驗證
-- 2. 生成存儲過程
DROP PROCEDURE IF EXISTS gen_test_data;
DELIMITER $$
CREATE PROCEDURE gen_test_data(IN p_total INT, IN p_batch INT)
BEGIN
DECLARE i INT DEFAULT 0;
-- 關鍵:關閉自動提交,手動控制事務邊界
SET autocommit = 0;
WHILE i < p_total DO
INSERT INTO `test` (`code`, `name`) VALUES ('sdfasdfas', 'aaa');
SET i = i + 1;
-- 每 p_batch 條提交一次
IF i % p_batch = 0 THEN
COMMIT;
-- 可選:進度日誌
-- INSERT INTO gen_log (cnt, ts) VALUES (i, NOW());
END IF;
END WHILE;
-- 餘數提交
COMMIT;
SET autocommit = 1;
END$$
DELIMITER ;
-- 3. 臨時切換 MyISAM(生成階段)
ALTER TABLE `test` ENGINE = MyISAM;
-- 4. 執行生成(1500萬條,每1000條提交)
CALL gen_test_data(15000000, 1000);
-- 5. 切回 InnoDB(業務驗證階段)
ALTER TABLE `test` ENGINE = InnoDB;
-- 6. 重建索引(如有二級索引)
-- ALTER TABLE `test` ADD INDEX idx_code (`code`);
ALTER TABLE ... ENGINE=InnoDB 會全表重建,1500 萬行約需數分鐘,需納入時間預算。ALTER TABLE test AUTO_INCREMENT=1 重置。
-- 生成前刪除所有二級索引
SHOW INDEX FROM `test` WHERE Key_name != 'PRIMARY';
-- 逐個 DROP INDEX ...
-- 生成後一次性添加
ALTER TABLE `test`
ADD INDEX idx_code (`code`),
ADD INDEX idx_name (`name`);
-- 或使用 LOAD DATA INFILE(更快,需文件準備)
-- 1. 存儲過程改為寫入 CSV 文件(SELECT ... INTO OUTFILE)
-- 2. LOAD DATA INFILE '/path/data.csv' INTO TABLE `test` ...
SELECT COUNT(*) FROM test; = 15000000SHOW TABLE STATUS LIKE 'test'\G → Auto_increment = 15000001SELECT code, COUNT(*) FROM test GROUP BY code; 全為 15000000ENGINE=InnoDB(切回後)ANALYZE TABLE test; 更新統計信息| 方案 | 生成 1500萬耗時 | 適用場景 | 缺點 |
|---|---|---|---|
| 存儲過程 + MyISAM + 批量提交 | ~3-5 分鐘 | 純 SQL 環境、無外部工具 | 佔用數據庫資源、表鎖 |
| sysbench / tpcc-mysql | ~2-3 分鐘 | 標準壓測、多線程並發 | 需安裝工具、學習成本 |
| Python/Java 多線程批量 INSERT | ~5-8 分鐘 | 應用層集成、動態數據構造 | 網絡開銷、連接池調優 |
| LOAD DATA INFILE | ~1-2 分鐘 | 大規模初始化、離線文件 | 需文件落盤、權限配置 |
「存儲過程 + MyISAM + 批量提交」是零依賴、純 SQL、秒級生成千萬測試數據的最佳平衡點。掌握引擎切換風險邊界,讓測試數據準備不再是壓測啟動的瓶頸。