理論皆灰綠,唯實測吐真金。本文記錄一個真實的千萬級數據分表實驗:從存儲過程自動拆分、索引策略調整、冗余列清理,到最終查詢效能的量化對比,還原分表優化的完整決策鏈路。
t_group,1038 萬行,字段:id (PK)、money、user_name、create_time。t_group_{user_name}。DELIMITER $$
CREATE PROCEDURE `sp_split_table`()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_user_name VARCHAR(20) DEFAULT '';
DECLARE v_table_name VARCHAR(64) DEFAULT '';
DECLARE cur1 CURSOR FOR SELECT user_name FROM t_group GROUP BY user_name;
DECLARE CONTINUE HANDLER FOR 1329 SET done = 1; -- No data
OPEN cur1;
WHILE done <> 1 DO
FETCH cur1 INTO v_user_name;
IF NOT done THEN
SET v_table_name = CONCAT('t_group_', v_user_name);
-- 1. 克隆結構
SET @stmt = CONCAT('CREATE TABLE ', v_table_name, ' LIKE t_group');
PREPARE s1 FROM @stmt; EXECUTE s1; DEALLOCATE PREPARE s1;
-- 2. 導入數據
SET @stmt = CONCAT('INSERT INTO ', v_table_name,
' SELECT * FROM t_group WHERE user_name = ''', v_user_name, '''');
PREPARE s1 FROM @stmt; EXECUTE s1; DEALLOCATE PREPARE s1;
END IF;
END WHILE;
CLOSE cur1;
SET @stmt = NULL;
END$$
DELIMITER ;
子表中 user_name 已無區分度(全表同值),佔用空間且干擾聚合掃描。執行:
ALTER TABLE t_group_david DROP COLUMN user_name;
耗時 7.58 秒 (129 萬行),後續聚合查詢顯著加速。
| 查詢類型 | 原大表 t_group | 分表 t_group_david (含 user_name) | 分表 t_group_david (刪 user_name) |
|---|---|---|---|
| COUNT(*) WHERE user_name='david' | 1.71 | 0.00 | 0.00 |
| COUNT(*) WHERE user_name<>'david' | 9.26 | — | 0.00 (子查詢相減) |
| MIN/MAX(money) WHERE user_name='david' | 0.00 (Full Index Scan) | 1.50 (Full Table Scan) | 0.00 |
| SUM/AVG(money) WHERE user_name='david' | 2.15 | 1.68 | 0.94 |
千萬級實測證明:分表 + 清理冗余列 + 索引重構 可將核心查詢從秒級降至毫秒級。分表非銀彈,但配合精細化優化,是突破單表效能天花板的必經之路。