什麼是索引
就像書籍的索引一樣,資料庫的索引可讓您快速地找到"資料表"或"索引檢視"中的特定資訊。索引中包含從"資料表"或"檢視"中一或多個資料行建立的索引鍵,並包含對應至指定資料儲存位置的指標。
您可以建立設計精良的索引來支援查詢,以大幅改善資料庫查詢及應用程式的效能。
索引可以減少必須讀取才能傳回查詢結果集的資料量。
索引也可以對資料表的資料列強制唯一性,以確保資料表資料的資料完整性。
索引基本概念
索引是一種與"資料表"或"檢視"有關的磁碟內存結構,它會加快從該資料表或檢視中擷取資料列的速度。
索引中包含從"資料表"或"檢視"中一或多個資料行建出的索引鍵。這些索引鍵儲存在結構中 (B 型樹狀目錄),讓 SQL Server 可以快速有效地找到與索引鍵值相關的一或多個資料列。資料表或檢視可包含下列類型的索引:
- 叢集
- 叢集索引將"資料表"或"檢視"中的資料列依其索引鍵值排序與儲存。這些就是索引定義中包含的資料行。因為資料列本身只能以一種順序排序,所以每個資料表只能有一個叢集索引。
- 只有當資料表包含叢集索引時,資料表中的資料列才會以排序順序儲存。當資料表有叢集索引時,資料表又稱為叢集資料表。如果資料表沒有任何叢集索引,它的資料列就儲存在未排序的結構中,這個結構稱為堆積。
- 非叢集
- 非叢集索引有一個與資料列完全分開的結構。非叢集索引包含非叢集索引鍵值,而每個索引鍵值項目都有一個指標,指向包含索引鍵值的資料列。
- 從非叢集索引中的索引列指向資料列的指標被稱為"資料列定位器"。
資料列定位器的結構須視資料頁儲存在堆積或叢集資料表而定。
若是堆積,資料列定位器是指向資料列的指標。
若是叢集資料表,資料列定位器就是叢集索引鍵。叢集與非叢集索引都可以是唯一的。這表示任何兩個資料列不得以相同的值做為索引鍵。
每當修改資料表的資料時,就會自動維護資料表或檢視的索引。
索引與條件約束
在資料表的資料行上定義 PRIMARY KEY 與 UNIQUE 條件約束時,會自動建立索引。
索引設計基本概念
設計不良的索引與不足的索引是資料庫應用程式瓶頸的主要原因。
設計有效的索引是達到良好資料庫和應用程式效能最重要的一點,為資料庫選擇正確的索引及工作負載時,往往很難在查詢速度與更新成本之間取得平衡。
範圍較小的索引或是索引的索引鍵中包含較少的資料行,所需的磁碟空間與維護負擔相對較小。
相反的,如果索引範圍較大,能涵蓋的查詢就更多。
在找到最有效率的索引之前,可能需要先試過數種不同的設計。
索引可以新增、修改和卸除,不會影響資料庫結構 描述或應用程式的設計。所以,不要吝於嘗試各種不同的索引。
下列工作是針對設計索引所建議的策略
- 瞭解資料庫本身的特性。
例如:這是經常修改資料的線上交易處理 (OLTP) 資料庫嗎?或是包含主要唯讀資料的決策支援系統 (DSS) 或資料倉儲 (OLAP) 資料庫? - 瞭解最常使用的查詢特性。
例如:知道最常使用的查詢會聯結兩個以上的資料表,將有助於判斷要使用的最佳類型索引。 - 瞭解用於查詢的資料行特性。
例如:對於具有整數資料類型的資料行且也是唯一或非 Null 的資料行來說,索引是最理想的方式。 - 建立或維護索引時,決定可能會提升效能的索引選項。
例如:ONLINE 索引選項對於在現有的大型資料表上建立叢集索引就有幫助。ONLINE 選項會在建立或重建索引的同時,允許繼續進行基礎資料上的並行活動。 - 決定最理想的索引儲存位置。非叢集索引可以作為基礎資料表儲存在相同的檔案群組中,或儲存在不同的檔案群組中。藉由增加磁碟 I/O 效能,索引的儲存位置可提升查詢效能。
例如:將非叢集索引儲存在不同磁碟機上 (與資料表檔案群組不同的磁碟機) 的檔案群組中,可以同時讀取多部磁碟機,所以可提升效能。
此外,叢集和非叢集索引可跨多個檔案群組使用資料分割配置。透過讓您快速及有效地存取或管理資料子集,分割可在維護整體集合的完整性時,讓大型資料 表或索引更容易管理。
當您考慮使用分割時,請決定是否應該校準索引,也就是說,使用分割資料表相同的方法進行分割,或獨立進行分割。
資料庫考量
- 資料表中的索引數量過多,會影響到 INSERT、UPDATE 與 DELETE 陳述式的執行效能,因為只要資料表中的資料一變更,所有的索引也都必須隨著調整。
- 請避免對時常更新的資料表過度索引,保持索引窄小,愈少資料行愈好。
- 對不常更新、但有大量資料的資料表使用多個索引可增進查詢效能。
大量索引可以協助不修改資料之查詢的效能,例如 SELECT 陳述式,因為查詢最佳化工具有較多的索引可供選擇,以判斷最快的存取方法。
- 為小型資料表建立索引並不是最佳的方式,因為查詢最佳化工具透過查閱索引來搜尋資料,會比執行簡單的資料表掃描更費時。
因此,在小型資料表上建立索引不僅很少使用,而且還必須在資料表變更時隨著資料維護。 - 當檢視包含彙總、資料表聯結或彙總與聯結的組合時,在檢視上建立索引可以提供重要的效能增進。
查詢中不必明確參考檢視,查詢最佳化工具會使用它。
查詢考量
- 在經常使用於述詞中,以及在查詢中使用聯結條件的所有資料行上建立非叢集索引。
- 重要: 避免加入不必要的資料行。加入太多索引資料行可能會對磁碟空間和索引維護效能產生不利的影響。
- 涵蓋索引可以增進查詢效能,因為查詢就存在於索引本身裡面,所有需要的資料都符合查詢的需求。也就是說,擷取要求的資料時只需要索引頁, 非資料表或叢集索引的資料頁;
因此,可以減少整體的磁碟 I/O。例如,某個資料表在 a 和 b 和 c 資料行上已建立複合的索引,則對資料行 a 和 b 查詢可以單獨從索引擷取指定的資料。 - 撰寫的查詢應盡可能在一個陳述式中插入或修改最多資料列,而不是使用多個查詢來更新同樣的資料列。
只使用一個陳述式,才能利用到最佳化的索引維護方式。 - 評估查詢類型,以及查詢中如何使用資料行。
例如,在完全相符查詢類型中使用的資料行,就很適合當作非叢集或叢集索引。