某 RSS 自動採集系統隨資料量增長,插入前的去重查詢越來越慢:
SELECT ID FROM wp_spost WHERE guid = 'https://news.sciencenet.cn/Htmlnews/2010/9/237832.shtm?id=237832';
guid 欄位儲存文章 URL,資料表約 20 萬筆,查詢耗時穩定在 0.55 ~ 0.60 秒,嚴重拖慢採集效能。
CREATE INDEX wdl_guid ON wp_spost(guid);
再次執行相同查詢:
SELECT ID FROM wp_spost WHERE guid = 'https://news.sciencenet.cn/Htmlnews/2010/9/237730.shtm?id=237730';
結果:0.00 秒(實測 < 1 ms),效能提升 500 倍以上。
| 無索引(全表掃描) | 有索引(B-Tree 查找) |
|---|---|
| 掃描 20 萬行,逐行比對字串 | 索引樹高度約 3 層,僅需 3 次頁面讀取 |
| I/O 成本高,CPU 做大量字串比較 | 直接定位到葉子節點,回表取 ID |
| 隨資料量線性增長 | 對數級增長,百萬筆仍在毫秒級 |
ID,可建立 INDEX idx_guid_id (guid, ID),實現「索引覆蓋」,完全避免回表。ALGORITHM=INPLACE, LOCK=NONE 線上 DDL,大表建議低峰期操作或用 pt-online-schema-change。slow_query_log,設定 long_query_time=0.1,定期用 pt-query-digest 分析,精準定位缺索引的 SQL。EXPLAIN SELECT ID FROM wp_spost WHERE guid = '...';
type=ref:非唯一索引查找(或 const 唯一索引)。key=wdl_guid:實際使用的索引名。rows=1:預估掃描行數,從 20 萬降為 1。Extra=Using index:觸發覆蓋索引(若只選索引欄位)。單欄索引是成本最低、收益最高的優化手段之一。本案例證實:針對高基數 WHERE 條件欄位建立 B-Tree 索引,可將全表掃描轉為毫秒級索引查找。養成「慢查詢 → EXPLAIN → 補索引 → 驗證」的閉環習慣,能解決 80% 以上的查詢效能問題。