偶爾在開發時會遇到查詢變慢的狀況,不禁懷疑:「加個 index 就能解決嗎?哪一種索引才有效?」這讓我決定做個簡單實驗,用 MySQL 建立一個大量資料表,實際對比有無索引、單一索引與複合索引下的查詢時間差異。
這篇筆記是我在 MySQL Workbench 上測試索引效能的記錄,包含從建立資料表、匯入測試資料到不同索引策略下的查詢結果與 EXPLAIN
分析。
database-index 是什麼?
簡單來說,就是:
建立測試資料表與大量資料,並實測各種索引設定對查詢速度的影響。
使用工具
- 📦 MySQL Workbench 8.0 CE
- 📁 測試資料:10,000 筆(t.sql)與 1.4 億筆資料(t4.sql)
測試資料與環境
建立資料庫與匯入
CREATE DATABASE `test_database`;
匯入資料檔案:
- t.sql(約 10,000 筆)
- t4.sql(約 139,000,000 筆)
產生測試資料
CREATE TABLE T(
Id INT AUTO_INCREMENT PRIMARY KEY,
UserId INT,
UserGroup INT
);
INSERT INTO T (UserId,UserGroup)
SELECT ROUND(1.0 + RAND() * 10000),
ROUND(1.0 + RAND() * 10000 / 1000) + 1
FROM information_schema.columns t1
CROSS JOIN information_schema.columns t
LIMIT 10000;
查詢效能測試:t 表(10,000 筆)
GROUP BY 查詢
SELECT count(*), UserId , UserGroup FROM t GROUP BY UserId;
SELECT count(*), UserId, GROUP_CONCAT(UserId), UserGroup, GROUP_CONCAT(UserGroup) FROM t GROUP BY UserId;
查詢特定值所需時間
SELECT * FROM t WHERE UserId = 1049 AND UserGroup = 11;
-- 花費時間:4.516 秒
增加索引後
ALTER TABLE `t` ADD INDEX `UserId` (`UserId`);
-- 查詢時間:1.938 秒 → 0.000 秒
測試其他索引組合
- 刪除
UserId
索引 - 保留
UserGroup
索引 → 查詢反而變慢(12.140 秒) - 增加複合索引:
ALTER TABLE `t` ADD INDEX `UserId_UserGroup` (`UserId`, `UserGroup`);
SELECT * FROM t WHERE UserId = 1049 AND UserGroup = 11;
查詢效能測試:t4 表(1.4 億筆)
無索引查詢
sql
コピーする編集するSELECT * FROM t4 WHERE UserId = 2423392 AND UserGroup = 38;
-- 花費時間:50 秒
加入索引後查詢
SELECT * FROM t4 WHERE UserId = 2423392 AND UserGroup = 38;
-- 花費時間:50 秒
刪除 UserId
索引,再增加 UserGroup
:
ALTER TABLE `t4` ADD INDEX `UserGroup` (`UserGroup`);
-- 查詢同樣降至 0 秒
加入複合索引:
ALTER TABLE `t4` ADD INDEX `UserGroup_UserId` (`UserGroup`, `UserId`);
使用 EXPLAIN 分析查詢計劃
條件:UserGroup + UserId
EXPLAIN SELECT * FROM t4 WHERE UserGroup = 38 AND UserId = 2423392;

單一條件查詢
僅 UserGroup
EXPLAIN SELECT * FROM t4 WHERE UserGroup = 38;
-- 預估 rows:5642904
僅 UserId(無索引)
EXPLAIN SELECT * FROM t4 WHERE UserId = 2423392;
-- rows: 139,000,000(使用全表掃描)
資料與索引體積比較
資料大小索引大小5647.00MB2831.98MB
為什麼我會做這個?
其實就是一個開發者的煩惱:
- 為什麼查詢那麼慢?
- 哪種索引最好用?
- 實際建資料試一下到底差多少?
與其紙上談兵,不如自己做個測試。
如果你也想試試
這份測試你也可以自己重現,只要準備好 MySQL Workbench,匯入上述 SQL 檔案並嘗試加入各種索引即可觀察查詢時間的差異。
這是個很好的練習,也適合拿來教學用來解釋「索引為什麼重要」。
如果你想直接下載或參考這份測試程式,歡迎看我的 GitHub:
歡迎交流
如果你也做過類似測試,或有自己觀察到的 index 效能經驗,歡迎留言交流分享:
你平常怎麼設計複合索引?遇過哪些「加了 index 反而變慢」的案例呢?
也許下一次的測試,就是解決這些問題的起點 🙌