InnoDB 使用 B+ 樹實作主索引與次要索引。當索引順序符合選擇性述詞、聯結、範圍掃描或排序需求時,索引可降低 I/O;但每個已索引資料列都會增加寫入工作與儲存空間。
叢集索引與次要索引 #
InnoDB 資料表會將資料列儲存在其叢集索引中。InnoDB 會選擇宣告的主索引鍵;否則會選擇第一個合適的非 NULL 唯一索引鍵,或建立內部隱藏索引鍵。請宣告短且穩定的主索引鍵,因為每個次要索引項目都會儲存主索引鍵值。
次要索引會儲存其索引欄位與主索引鍵值。需要次要索引中不存在欄位的查詢,會為每個相符項目執行叢集索引查詢。只有在能移除已量測成本時才加入涵蓋索引;較寬的索引會降低頁面扇出並增加寫入負荷。
複合索引 #
對於 (tenant_id, created_at, id),B+ 樹可以有效定位:
WHERE tenant_id = ? AND created_at >= ?
ORDER BY created_at, id它無法只從 created_at 有效搜尋,因為樹的順序以 tenant_id 開始。一般設計會讓等值述詞先於範圍述詞,接著放置滿足排序或涵蓋需求的欄位。請使用 EXPLAIN ANALYZE 驗證選擇;索引順序取決於實際述詞、資料分布與結果大小。
索引類型與診斷 #
UNIQUE 除了建立存取路徑,也會強制執行不變量。大多數 InnoDB 索引都是 B 樹。FULLTEXT 索引支援以 token 為基礎的文字搜尋,而幾何值上的 SPATIAL 索引使用 R 樹。MySQL 也描述 MEMORY 引擎的雜湊索引;InnoDB 不公開一般雜湊索引,但其自適應雜湊索引可以將頻繁存取的 B 樹頁面快取為內部最佳化。前綴索引可以減少長文字鍵的位元組大小,但前提是所選前綴仍具選擇性。
EXPLAIN ANALYZE
SELECT id, created_at
FROM event
WHERE tenant_id = 7
AND created_at >= '2026-01-01'
ORDER BY created_at, id
LIMIT 100;請檢查實際資料列、迴圈次數與計時,而不要假設會使用索引。統計資料、基數估計與小型結果集可能使資料表掃描比索引走訪更便宜。
SHOW INDEX 回報的是估計基數,而非精確的不重複值數量。必要時使用 ANALYZE TABLE 重新整理過時統計資料,然後以 EXPLAIN ANALYZE 的測量值比較最佳化器估計。不可見索引可讓管理員在 InnoDB 持續維護索引的同時,像索引不存在一樣測試計畫:
ALTER TABLE event ALTER INDEX event_tenant_created INVISIBLE;
ALTER TABLE event ALTER INDEX event_tenant_created VISIBLE;在檢查代表性查詢與限制需求前,不要刪除索引。每個額外索引都會消耗頁面,並增加插入、刪除、更新、重做記錄、緩衝池、備份與複寫工作。因此,索引選擇必須在已量測的讀取效益、寫入放大與操作成本之間取得平衡。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)