在聯機交易處理 (OLTP) 系統中,查詢速度決定系統成敗。索引是加速查詢最直接手段,但不當索引反拖累寫入效能。本文系統梳理索引類型選擇、設計技巧、維護策略與避坑指南。
將實體資料依指定欄位重新排序儲存,索引葉節點即資料頁。每表僅一個,建立需 120% 額外空間。
BETWEEN, >, <, ≥, ≤)、GROUP BY/ORDER BY 欄位:資料物理連續,找到首筆即可順序讀取,避免大範圍掃描。WHERE 子句與 Join 類型選擇。WHERE 常用、插入隨機)。pri_order BETWEEN 100 AND 200)。GROUP BY/ORDER BY 常用欄位。不重組資料,葉節點儲存索引鍵值 + 書籤指向資料列(Heap 情況為 RID,叢集表為叢集鍵)。預設建立類型,無叢集索引表最多 250 個非叢集索引。
SUM, AVG 等)欄位。JOIN, ORDER BY, GROUP BY 欄位。更新頻繁表上,非叢集索引維護成本 > 叢集索引 > 無索引。每列移動/刪除需同步更新所有非叢集索引書籤,甚至引發索引分頁分裂。
非叢集索引葉節點包含查詢所需所有欄位(INCLUDE 欄位或複合索引涵蓋),查詢無需回表(Key Lookup),速度可超越叢集索引。
代價:索引體積大、UPDATE 導致索引值變更維護成本高。僅對高頻、關鍵查詢建立;低頻查詢反降低整體效能。
測試環境:89 萬列住房公積金明細表,C/S 架構,客戶端 PII 350/64MB,伺服器 Alpha 1000A/128MB,Sybase 11.0.3(原理通用)。
| 查詢 | 無索引 | op_date 非叢集 | op_date 叢集 | pay_month,op_date,pri_surplus1 非叢集 | op_date,pay_month,pri_surplus1 非叢集 |
|---|---|---|---|---|---|
1. op_date 範圍 + pri_surplus1>300 | 1分15秒 | 57秒 | <1秒 | 34秒 | <1秒 |
2. op_date 範圍 + pay_month 範圍 | 1分7秒 | 57秒 | 52秒 | <1秒 | <1秒 |
結論:索引欄位順序決定成敗。查詢 1 需 op_date 先行(範圍條件),查詢 2 需 pay_month 先行。複合索引首欄必須為最高選擇性/最常用範圍條件欄位。
WHERE/Join,建叢集索引(插入隨機時)。UNIQUE 索引,優化器可生成更優計畫。FILLFACTOR 預留空間減少分頁分裂,提升併發降低死鎖;唯讀表設 100。INT 優於 BIGINT/CHAR),單頁容納更多鍵值,減少樹高與 I/O。整數鍵值存取最快。重新組織 B-Tree 空間,消除碎片,恢復大塊 I/O 效率。觸發條件:
DBCC 檢測索引異常。注意:重建叢集索引會連帶重建所有非叢集索引。
優化器依賴分布頁(密度向量 + 直方圖)判斷索引效用。統計資訊非即時更新,資料分佈變動後必須手動 UPDATE STATISTICS:
TRUNCATE TABLE 後重新載入資料。WHERE/JOIN 從未引用的欄位:索引純屬負擔。權衡策略:將表置於一個檔案群組,非叢集索引置於另一獨立物理裝置檔案群組,平衡讀寫 I/O。