當單表資料量過大 (如用戶訪問日誌) 導致查詢效能下降,分表是常見優化手段。MySQL 的 MERGE 存儲引擎 (又稱 MRG_MyISAM) 提供邏輯分表與統一查詢介面:將多個結構相同的 MyISAM 表聚合為一個虛擬總表,應用層無感知即可跨分片查詢。本文詳細介紹 MERGE 表的創建、使用、映射維護與限制規則。
t1、t2)-- 建立分表 t1、t2 (結構完全一致,引擎 MyISAM)
CREATE TABLE t1 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
message CHAR(20)
) ENGINE=MyISAM;
CREATE TABLE t2 (
a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
message CHAR(20)
) ENGINE=MyISAM;
-- 插入測試資料
INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');
INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');
-- 建立總表 (MERGE 引擎)
CREATE TABLE total (
a INT NOT NULL AUTO_INCREMENT,
message CHAR(20),
INDEX(a)
) ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
| 參數 | 值選項 | 行為 |
|---|---|---|
| UNION | (t1,t2,...) | 指定聚合的分表列表,查詢時掃描所有列表表 |
| INSERT_METHOD | NO / FIRST / LAST | NO=禁止總表插入;FIRST=插入第一張分表;LAST=插入最後一張分表 |
mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table |
| 3 | t1 |
| 1 | Testing |
| 2 | table |
| 4 | t2 |
+---+---------+
6 rows in set (0.00 sec)
總表可見所有分表資料,且支援 SELECT、DELETE、UPDATE、INSERT (需分表相應權限)。
DROP TABLE total;
CREATE TABLE total (...) ENGINE=MERGE UNION=(t1,t2,t3) INSERT_METHOD=LAST;
ALTER TABLE total UNION=(t1,t2,t3);
注意:UNION=() (空列表) 會導致總表無資料且無法插入 (MySQL 不知道寫入哪個分表)。
MySQL 不在創建總表時檢查,僅在打開查詢時驗證。違規會導致總表無法打開,使用 CHECK TABLE total 可定位問題分表。
| 優點 | 缺點 |
|---|---|
| 應用層透明,無需修改查詢邏輯 | 僅支援 MyISAM,無事務、無行鎖、崩潰不安全 |
| 分表獨立維護,歸檔/刪除舊分表極簡單 | 跨分表唯一性約束無法保證 (總表無 PK) |
| 單表體積小,索引效率高 | 大量分表時 OPEN_TABLE_LIMIT 可能不足 |
| INSERT_METHOD 靈活控制寫入目標 | 不支援 REPLACE、不支援 AUTO_INCREMENT 衝突處理 |
MySQL 5.1+ 引入 原生分區表,5.7+ 增強分區剪枝;MySQL 8.0 + ShardingSphere/ProxySQL 或 Vitess 提供透明分庫分表。MERGE 適用於:
MERGE 引擎以「視圖式聚合」實現邏輯分表,核心優勢在於零改造應用層查詢。但受限於 MyISAM 缺陷與一致性要求嚴格,現代新系統建議優先考慮原生分區表或中介軟體分片方案。維護既有 MERGE 系統時,嚴守結構一致性規則、善用 CHECK TABLE 診斷、謹慎規劃 INSERT_METHOD 是穩定運行關鍵。