「尋找最短索引做覆蓋掃描時,若主鍵為聚簇索引,不再考慮完整行長度。二級覆蓋索引將被優先選擇,減少全表掃描。」
新增 find_shortest_key() 函數:選擇 key_len 最小的覆蓋索引。若 Primary_key_is_clustered() 回傳 true(InnoDB),則**不考慮主鍵**,改用最短二級索引。
CREATE TABLE test (
id INT, name VARCHAR(20), name2 VARCHAR(20), d DATETIME,
PRIMARY KEY (id)
) ENGINE=InnoDB;
INSERT INTO test VALUES ... (10 筆測試資料)
-- 只建主鍵
EXPLAIN SELECT COUNT(*) FROM test;
-- key=PRIMARY, key_len=4
-- 加入 ind_1(name, d)
ALTER TABLE test ADD INDEX ind_1(name, d);
EXPLAIN SELECT COUNT(*) FROM test;
-- key=PRIMARY, key_len=4 ← 仍選主鍵
-- 加入 ind_2(d)
ALTER TABLE test ADD INDEX ind_2(d);
EXPLAIN SELECT COUNT(*) FROM test;
-- key=PRIMARY, key_len=4 ← 仍選主鍵
5.1.45 **總是選主鍵**,忽略更短的二級索引。
-- 加入 ind_1(name, d)
EXPLAIN SELECT COUNT(*) FROM test;
-- key=ind_1, key_len=52 ← 選擇 ind_1
-- 加入 ind_2(d)
EXPLAIN SELECT COUNT(*) FROM test;
-- key=ind_2, key_len=9 ← 選擇更短的 ind_2
5.1.48 **智能選擇最短二級覆蓋索引**,不再盲目用主鍵。
| 版本 | 執行時間 | Sending data 耗時 |
|---|---|---|
| 5.1.45 | 1.30 秒 | 1.294 秒 |
| 5.1.48 | 1.18 秒 | 1.178 秒 |
掃描較短的二級索引頁面,**減少約 9% I/O 耗時**。
DB_TRX_ID、DB_ROLL_PTR 等,約 20 bytes)COUNT(*) 只需掃描索引,**掃描最小索引最快**💡 結論:InnoDB 表建議**永遠有自增主鍵**,並視查詢需求建立適當二級索引。新版優化器會自動選擇最輕量的覆蓋索引執行 COUNT(*) 等全掃查詢。