共用方式為


ALTER INDEX (Transact-SQL)

適用於:Microsoft Fabric 中的 SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics AnalyticsPlatform System (PDW)SQL Database

藉由停用、重建或重新組織索引或設定索引選項,修改現有的資料表或檢視表索引 (資料列存放區、資料行存放區或 XML)。

Transact-SQL 語法慣例

Syntax

SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體 的語法。

ALTER INDEX { index_name | ALL } ON <object>
{
      REBUILD {
            [ PARTITION = ALL [ WITH ( <rebuild_index_option> [ , ...n ] ) ] ]
          | [ PARTITION = partition_number [ WITH ( <single_partition_rebuild_index_option> [ , ...n ] ) ] ]
      }
    | DISABLE
    | REORGANIZE  [ PARTITION = partition_number ] [ WITH ( <reorganize_option>  ) ]
    | SET ( <set_index_option> [ , ...n ] )
    | RESUME [ WITH (<resumable_index_option> [ , ...n ] ) ]
    | PAUSE
    | ABORT
}
[ ; ]

<object> ::=
{
    { database_name.schema_name.table_or_view_name | schema_name.table_or_view_name | table_or_view_name }
}

<rebuild_index_option> ::=
{
      PAD_INDEX = { ON | OFF }
    | FILLFACTOR = fillfactor
    | SORT_IN_TEMPDB = { ON | OFF }
    | IGNORE_DUP_KEY = { ON | OFF }
    | STATISTICS_NORECOMPUTE = { ON | OFF }
    | STATISTICS_INCREMENTAL = { ON | OFF }
    | ONLINE = { ON [ ( <low_priority_lock_wait> ) ] | OFF }
    | RESUMABLE = { ON | OFF }
    | MAX_DURATION = <time> [ MINUTES ]
    | ALLOW_ROW_LOCKS = { ON | OFF }
    | ALLOW_PAGE_LOCKS = { ON | OFF }
    | MAXDOP = max_degree_of_parallelism
    | DATA_COMPRESSION = { NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE }
        [ ON PARTITIONS ( { <partition_number> [ TO <partition_number> ] } [ , ...n ] ) ]
    | XML_COMPRESSION = { ON | OFF }
        [ ON PARTITIONS ( { <partition_number> [ TO <partition_number> ] } [ , ...n ] ) ] }

<single_partition_rebuild_index_option> ::=
{
      SORT_IN_TEMPDB = { ON | OFF }
    | MAXDOP = max_degree_of_parallelism
    | RESUMABLE = { ON | OFF }
    | MAX_DURATION = <time> [ MINUTES ]
    | DATA_COMPRESSION = { NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE }
    | XML_COMPRESSION = { ON | OFF }
    | ONLINE = { ON [ ( <low_priority_lock_wait> ) ] | OFF }
}

<reorganize_option> ::=
{
       LOB_COMPACTION = { ON | OFF }
    |  COMPRESS_ALL_ROW_GROUPS =  { ON | OFF }
}

<set_index_option> ::=
{
      ALLOW_ROW_LOCKS = { ON | OFF }
    | ALLOW_PAGE_LOCKS = { ON | OFF }
    | OPTIMIZE_FOR_SEQUENTIAL_KEY = { ON | OFF }
    | IGNORE_DUP_KEY = { ON | OFF }
    | STATISTICS_NORECOMPUTE = { ON | OFF }
    | COMPRESSION_DELAY = { 0 | delay [ Minutes ] }
}

<resumable_index_option> ::=
 {
    MAXDOP = max_degree_of_parallelism
    | MAX_DURATION = <time> [ MINUTES ]
    | <low_priority_lock_wait>
 }

<low_priority_lock_wait> ::=
{
    WAIT_AT_LOW_PRIORITY ( MAX_DURATION = <time> [ MINUTES ] ,
                          ABORT_AFTER_WAIT = { NONE | SELF | BLOCKERS } )
}

Azure Synapse Analytics 和分析平台系統 (PDW) 的語法。

ALTER INDEX { index_name | ALL }
    ON [ schema_name. ] table_name
{
      REBUILD {
            [ PARTITION = ALL [ WITH ( <rebuild_index_option> ) ] ]
          | [ PARTITION = partition_number [ WITH ( <single_partition_rebuild_index_option> ) ] ]
      }
    | DISABLE
    | REORGANIZE [ PARTITION = partition_number ]
}
[ ; ]

<rebuild_index_option> ::=
{
    DATA_COMPRESSION = { COLUMNSTORE | COLUMNSTORE_ARCHIVE }
        [ ON PARTITIONS ( { <partition_number> [ TO <partition_number> ] } [ , ...n ] ) ]
    | XML_COMPRESSION = { ON | OFF }
        [ ON PARTITIONS ( { <partition_number> [ TO <partition_number> ] } [ , ...n ] ) ]
}

<single_partition_rebuild_index_option> ::=
{
    DATA_COMPRESSION = { COLUMNSTORE | COLUMNSTORE_ARCHIVE }
    | XML_COMPRESSION = { ON | OFF }
}

引數

index_name

索引的名稱。 在資料表或檢視內,索引名稱必須是唯一,但在資料庫內就不一定要唯一。 索引名稱必須遵照識別碼的規則。

ALL

指定與資料表或檢視表相關聯的所有索引 (不論索引類型為何)。 ALL如果一或多個索引位於離線或唯讀檔案群組中,或一或多個索引類型上不允許指定的作業,則指定會導致語句失敗。 下表列出索引作業和不允許的索引類型。

搭配此作業使用 關鍵詞 ALL 如果資料表有一個或多個下列項目,便告失敗
REBUILD WITH ONLINE = ON XML 索引

空間索引

SQL Server 2017(14.x) 和舊版中的數據行存放區索引。 較新版本支持數據行存放區索引的在線重建。
REBUILD PARTITION = <partition_number> 未分割索引、XML 索引、空間索引或停用的索引
REORGANIZE 設定為的 ALLOW_PAGE_LOCKS 索引 OFF
REORGANIZE PARTITION = <partition_number> 未分割索引、XML 索引、空間索引或停用的索引
IGNORE_DUP_KEY = ON XML 索引

空間索引

數據行存放區索引 1
ONLINE = ON XML 索引

空間索引
數據行存放區索引 1
RESUMABLE = ON ALL 關鍵詞不支援可繼續索引

如果使用 ALL 指定 PARTITION = <partition_number>,則所有索引都必須對齊。 這表示其會根據對等的分割區函數來進行分割。 使用 ALL with PARTITION 會導致所有具有相同 <partition_number> 的索引分割區重建或重新組織。 如需數據分割索引的詳細資訊,請參閱 分割數據表和索引

如需在線索引作業的詳細資訊,請參閱 在線索引作業的指導方針

database_name

資料庫的名稱。

schema_name

資料表或檢視所屬之結構描述的名稱。

table_or_view_name

這是與索引相關聯的資料表或檢視表的名稱。 若要檢視數據表或檢視表的索引詳細數據,請使用 sys.indexes 目錄檢視。

<database_name> 為目前資料庫名稱時,Azure SQL Database 支援三部分名稱格式 <database_name>.<schema_name>.<object_name>,或 <database_name>tempdb,且 <object_name> 開頭為 ###。 如果架構名稱是 dbo,則可以省略 <schema_name>

REBUILD [ WITH ( <rebuild_index_option> [ ,... n ] ] ]

適用於:SQL Server 2012 (11.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

指定使用相同的數據行、索引類型、唯一性屬性和排序順序重建索引。 REBUILD 會啟用停用的索引。 除非指定 關鍵詞 ALL ,否則重建叢集索引不會重建相關聯的非叢集索引。 如果未指定索引選項,則會套用 sys.indexes 中的現有索引選項值。 對於值未出現在 sys.indexes的任何索引選項,選項的自變數定義中會套用預設值。

如果指定了 ALL,而且基礎表是堆積,則重建作業不會影響堆積。 與資料表相關聯的任何非叢集索引都會重建。

如果資料庫恢復模式是大容量日誌或簡單,則 REBUILD 作業可以最低限度記錄。

當您重建主要 XML 索引時,在索引作業的持續時間,無法使用基礎使用者資料表。

針對資料行存放區索引,重建作業:

  • 將所有資料重新壓縮到資料行存放區。 重建作業進行時,有兩份數據行存放區索引複本存在。 重建完成時,Database Engine 會刪除原始的數據行存放區索引。
  • 如果有任何,則不會保留排序順序。 若要重建數據行存放區索引並保留或引入排序順序,請使用 CREATE [CLUSTERED] COLUMNSTORE INDEX ... ORDER (...) ... WITH (DROP_EXISTING = ON) 語句。

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

PARTITION

指定只重建或重新組織索引的一個分割區。 PARTITION 如果 index_name 不是資料分割索引,則無法指定 。

PARTITION = ALL 重建所有分割區。

警告

在具有超過 1,000 個數據分割的數據表上建立和重建非對齊索引是可行的,但不受支援。 這樣做可能會導致效能降低,或在這些作業期間耗用過多的記憶體。 Microsoft建議只有在分割區數目超過 1,000 時,才使用對齊的索引。

  • partition_number

    要重建或重新組織的分割區索引分割區數。 partition_number 是一個可以參考變數的常數運算式。 其中包括使用者定義類型變數或函數及使用者定義函數,但無法參考 Transact-SQL 陳述式。 partition_number必須存在,否則陳述式將會失敗。

  • WITH ( <single_partition_rebuild_index_option> )

    SORT_IN_TEMPDBMAXDOPDATA_COMPRESSIONXML_COMPRESSION 是使用 (PARTITION = partition_number) 語法重建單一分割區時可以指定的選項。 無法在單一數據分割重建作業中指定 XML 索引。

DISABLE

將索引標示為已停用,無法供資料庫引擎使用。 任何索引都可以停用。 已停用之索引的索引定義會保留在系統目錄中,但不含基礎索引資料。 停用叢集索引可以防止使用者存取基礎資料表資料。 若要啟用索引,請使用 ALTER INDEX REBUILDCREATE INDEX WITH DROP_EXISTING。 如需詳細資訊,請參閱 停用索引和條件約束啟用索引和條件約束

REORGANIZE 資料列存放區索引

針對數據列存放區索引, REORGANIZE 指定重新組織索引分葉層級。 此 REORGANIZE 工作為:

  • 一律在線上執行。 這表示不會保留長期封鎖數據表鎖定,而且基礎表中的數據查詢或更新可以在 ALTER INDEX REORGANIZE 交易期間繼續。
  • 不允許使用停用的索引。
  • 當 設定為 ALLOW_PAGE_LOCKSOFF,不允許。
  • 在交易內執行且交易回復時,不會回復。

注意

ALTER INDEX REORGANIZE 使用明確交易 (例如 ALTER INDEX 內的 BEGIN TRAN ... COMMIT/ROLLBACK) 而非預設的隱含交易模式時,REORGANIZE 的鎖定行為會變得更加嚴格,可能因此導致封鎖。 如需隱含交易的詳細資訊,請參閱 SET IMPLICIT_TRANSACTIONS

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

REORGANIZE WITH ( LOB_COMPACTION = { ON | OFF } )

適用於資料列存放區索引。

  • ON

    • 指定壓縮包含下列大型物件 (LOB) 資料類型資料的所有頁面:imagetextntextvarchar(max)nvarchar(max)varbinary(max)xml。 壓縮此資料可縮小磁碟上的資料大小。
    • 對於叢集索引,這會壓縮資料表中包含的所有 LOB 資料行。
    • 對於非叢集索引,這會壓縮索引中本身是非索引鍵資料行 (內含資料行) 的所有 LOB 資料行。
    • REORGANIZE ALL 在所有索引上執行LOB壓縮。 對於每個索引,這會壓縮叢集索引中的所有 LOB 資料行、基礎資料表,或非叢集索引中包含的資料行。
  • OFF

    • 不壓縮包含大型物件資料的頁面。
    • OFF 對堆積沒有任何作用。

REORGANIZE 資料行存放區索引

針對數據行存放區索引,REORGANIZE 將每個封閉的差異數據列群組壓縮到數據行存放區中,做為壓縮的數據列群組。 REORGANIZE 作業一律會在線上執行。 這表示不會保留長期封鎖的資料表鎖定,而且在 ALTER INDEX REORGANIZE 交易期間,可以繼續查詢或更新基礎資料表。

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

  • 不需要 REORGANIZE,才能將封閉的差異數據列群組移至壓縮的數據列群組。 背景 Tuple 行動器 (TM) 進程會定期喚醒,以壓縮已關閉的差異數據列群組。 建議您在元組移動器落後時使用 REORGANIZEREORGANIZE 可以更積極地壓縮數據列群組。
  • 若要壓縮所有開啟和關閉的數據列群組,請參閱 REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS)

針對 SQL Server 2016(13.x) 和更新版本中的數據行存放區索引,Azure SQL Database 和 Azure SQL 受控實例,REORGANIZE 在線執行下列額外的重組優化:

  • 當 10 個% 或多個資料列已以邏輯方式刪除時,從數據列群組中實際移除已刪除的數據列。 已刪除的位元組會在實體媒體上回收。 例如,如果 1 百萬個數據列的壓縮數據列群組已刪除 100,000 個數據列,Database Engine 會移除已刪除的數據列,並以 900,000 個數據列重新壓縮數據列群組。

  • 可合併一或多個壓縮的資料列群組,將每個資料列群組的資料列數目最多提高至 1,048,576 個資料列的上限。 例如,如果您大容量導入 5 批 102,400 個數據列,則會收到 5 個壓縮的數據列群組。 如果您執行 REORGANIZE,這些數據列群組會合併成1個壓縮的數據列群組,其中包含512,000個數據列。 這假設沒有字典大小或記憶體限制。

  • 對於邏輯刪除 10 個% 或多個數據列的數據列群組,Database Engine 會嘗試將此數據列群組與一或多個數據列群組結合。 例如,資料列群組 1 壓縮了 500,000 個資料列,而資料列群組 21 則壓縮了達到數目上限的 1,048,576 個資料列。 資料列群組 21 中刪除了 60% 的資料列,剩下 409,830 個資料列。 Database Engine 偏好合併這兩個數據列群組,以壓縮具有 909,830 個數據列的新數據列群組。

REORGANIZE WITH ( COMPRESS_ALL_ROW_GROUPS = { ON | OFF } )

適用資於料行存放區索引。

適用於: SQL Server 2016 (13.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

COMPRESS_ALL_ROW_GROUPS 可讓您強制開啟或關閉差異數據列群組進入數據行存放區。 使用此選項時,不需要重建資料行存放區索引來清空差異資料列群組。 結合其他移除和合併重組功能,這讓大部分情況下不再需要重建數據行存放區索引。

  • ON

    強制所有數據列群組進入數據行存放區,而不論大小和狀態為何(已關閉或開啟)。

  • OFF

    強制所有已關閉的數據列群組進入數據行存放區。

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

SET ( <set_index 選項> [ ,... n ]

修改索引選項,而不重建或重新組織索引。 SET 無法為停用的索引指定。

PAD_INDEX = { ON | OFF }

指定索引填補。 預設值為 OFF

  • ON

    填滿因數所指定的可用空間百分比會套用至索引的中繼層級頁面。 如果未同時指定 FILLFACTORPAD_INDEX 設定為 ON,則會使用 sys.indexes 中的填滿因數值

  • OFF

    中繼層級頁面會填入接近容量,考慮到中繼頁面上的索引鍵集,為索引所能擁有的大小上限至少一個數據列留下足夠的空間。 如果 PAD_INDEX 設定為 ON 但未指定填滿因數,也會發生這種情況。

如需詳細資訊,請參閱 CREATE INDEX

FILLFACTOR = fillfactor

指定百分比,以表示 Database Engine 在索引建立或變更期間應該將每個索引頁面的分葉層級填滿的程度。 [fillfactor] 必須是 1 到 100 之間的整數值。 預設值是 0。 填滿因數值 0 和 100 在各方面都是一樣的。

只有在最初建立或重建索引時,才適用明確的 FILLFACTOR 設定。 資料庫引擎不會動態保留頁面中空白空間的指定百分比。 如需詳細資訊,請參閱 CREATE INDEX

若要檢視填滿因數設定,請使用 fill_factor 中的 sys.indexes

重要

建立 FILLFACTOR 小於 100 的索引會增加數據佔用的儲存空間量,因為 Database Engine 會在建立或重建索引時,根據填滿因數重新發佈數據。

SORT_IN_TEMPDB = { ON | OFF }

指定是否要將暫存排序結果儲存在 tempdb中。 預設值為 OFF Azure SQL 資料庫 超大規模資料庫除外。 針對超大規模資料庫中的所有索引建置作業,除非使用可繼續的索引組建,否則一律會 ONSORT_IN_TEMPDB。 針對可繼續的索引組建,SORT_IN_TEMPDB 一律會 OFF

  • ON

    用來建置索引的中繼排序結果會儲存在 中 tempdb。 這可能會縮短建立索引所需的時間。 不過,這會增加建立索引時所使用的磁碟空間量。

  • OFF

    中繼排序結果會儲存在與用來儲存索引相同的資料庫中。

如果不需要排序作業,或排序可在記憶體中執行,即忽略 SORT_IN_TEMPDB 選項。

如需詳細資訊,請參閱索引 SORT_IN_TEMPDB 選項。

IGNORE_DUP_KEY = { ON | OFF }

指定當插入作業嘗試將重複的索引鍵值插入唯一索引時所產生的錯誤回應。 IGNORE_DUP_KEY 選項只適用於在建立或重新編製索引之後所發生的插入作業。 預設值為 OFF

  • ON

    當重複的索引鍵值插入唯一索引時,就會出現警告訊息。 只會插入違反唯一性條件約束的數據列。

  • OFF

    當重複的索引鍵值插入唯一索引時,就會出現錯誤訊息。 整個 INSERT 作業都會回復。

IGNORE_DUP_KEY 無法在檢視表、非唯一索引、XML 索引、空間索引和篩選索引上建立的索引設定為 ON

若要檢視索引的 IGNORE_DUP_KEY 設定,請使用 sys.indexes 目錄檢視中的 ignore_dup_key 數據行。

在與舊版本相容的語法中,WITH IGNORE_DUP_KEY 相當於 WITH IGNORE_DUP_KEY = ON

STATISTICS_NORECOMPUTE = { ON | OFF }

針對索引上的統計數據,停用或啟用自動統計數據更新選項 AUTO_STATISTICS_UPDATE。 預設值為 OFF

  • ON

    重新建置索引之後,就會停用自動統計數據更新。

  • OFF

    重新建置索引之後,就會啟用自動統計數據更新。

若要還原自動更新統計數據,請將 設定STATISTICS_NORECOMPUTEOFF,或在沒有 子句的情況下UPDATE STATISTICS執行NORECOMPUTE

警告

如果您藉由設定 STATISTICS_NORECOMPUTE = ON來停用統計數據的自動重新計算,您可能會防止查詢優化器為涉及數據表的查詢挑選最佳執行計劃。

STATISTICS_NORECOMPUTE 設定為 ON,並不會防止在索引重建作業期間發生的索引統計數據更新。

STATISTICS_INCREMENTAL = { ON | OFF }

適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

ON時,在索引上建立的統計數據是每個分割區統計數據。 當 OFF時,會卸除現有的統計數據,而 Database Engine 會重新計算統計數據。 預設值為 OFF

如果不支援每個分割區統計數據,則會忽略選項並產生警告。 在下列情況下不支援累加統計資料:

  • 建立統計資料時,所使用的索引未與基底資料表進行分割區對齊
  • 在可用性群組可讀取次要資料庫上建立的統計資料
  • 在唯讀資料庫上建立的統計資料
  • 在篩選的索引上建立的統計資料
  • 在檢視表上建立的統計資料
  • 在內部資料表上建立的統計資料
  • 使用空間索引或 XML 索引建立的統計資料

ONLINE = { ON |OFF }

指定在索引作業期間,查詢和資料修改是否能夠使用基礎資料表和相關聯的索引。 預設值為 OFF

若為 XML 索引或空間索引,則僅 ONLINE = OFF 支援 ,如果 ONLINE 設定為 ON 錯誤,則為 。

重要

並非所有 Microsoft SQL Server 版本都提供線上編製索引作業。 如需 SQL Server 版本支援的功能清單,請參閱 SQL Server 2022 的版本和支援功能

  • ON

    在索引作業期間,不會保留長期數據表鎖定。 在索引作業的主要階段,源數據表上只會保留意圖共享 (IS) 鎖定。 這可讓基礎表和索引的查詢或更新繼續進行。 作業開始時,來源物件上會保留一段短暫的共用(S)鎖定。 作業結束時,如果正在建立非叢集索引,則會在物件上取得共用 (S) 鎖定。 建立或卸除叢集索引時,以及重建叢集或非叢集索引時,會取得架構修改 (Sch-M) 鎖定。 ONLINE 在本機暫存表上建立索引時,無法設定為 ON

    注意

    您可以使用 [WAIT_AT_LOW_PRIORITY] 選項來減少或避免在在線索引作業期間封鎖。 如需詳細資訊,請參閱使用在線索引作業 WAIT_AT_LOW_PRIORITY

  • OFF

    數據表鎖定會套用到索引作業的持續時間。 建立、重建或卸除叢集、空間或 XML 索引的離線索引作業,或重建或卸除非叢集索引,取得資料表上的架構修改 (Sch-M) 鎖定。 這可防止所有用戶在作業期間存取基礎表。 建立非叢集索引的離線索引作業一開始會取得數據表上的共用 (S) 鎖定。 這可防止修改基礎表定義,但允許在索引建置進行時讀取和修改數據表中的數據。

如需詳細資訊,請參閱 線上執行索引作業 和在線索引作業 指導方針

您可以在線上重建索引,其中包括全域暫存資料表的索引,但下列情況除外:

  • XML 索引
  • 本機暫存資料表上的索引
  • 在檢視上的初始唯一叢集索引
  • 已停用的叢集索引
  • SQL Server 2017(14.x)和舊版中的叢集數據行存放區索引
  • SQL Server 2016(13.x)和舊版中的非叢集數據行存放區索引
  • 叢集索引 (如果基礎資料表包含 LOB 資料類型 (imagentexttext) 及空間類型)
  • varchar(max)varbinary(max) 數據行不能是索引鍵的一部分。 從 SQL Server 2012 (11.x)開始,在 Azure SQL Database 和 Azure SQL 受控實例中,當數據表包含 varchar(max)varbinary(max) 數據行時,可以使用 ONLINE 選項來建置或重建包含其他數據行的叢集索引。

如需詳細資訊,請參閱 在線索引作業的運作方式

RESUMABLE = { ON | OFF}

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

指定線上索引作業是否為可繼續的作業。

  • ON

    索引作業為可繼續的作業。

  • OFF

    索引作業不是可繼續的作業。

MAX_DURATION = 時間 [ MINUTES ] 搭配 RESUMABLE = ON 使用 (需要 ONLINE = ON

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

指定在暫停之前執行可繼續索引作業的時間,以整數分鐘為單位。

ALLOW_ROW_LOCKS = { ON | OFF }

指定是否允許資料列鎖定。 預設值為 ON

  • ON

    當存取索引時,允許資料列鎖定。 資料庫引擎會決定使用資料列鎖定的時機。

  • OFF

    不會使用資料列鎖定。

ALLOW_PAGE_LOCKS = { ON | OFF }

指定是否允許頁面鎖定。 預設值為 ON

  • ON

    當您存取索引時,允許頁面鎖定。 資料庫引擎會決定使用頁面鎖定的時機。

  • OFF

    不會使用頁面鎖定。

OPTIMIZE_FOR_SEQUENTIAL_KEY = { ON | OFF }

適用於:SQL Server 2019 (15.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

指定是否要優化以避免最後一頁插入爭用。 預設值為 OFF。 如需詳細資訊,請參閱 循序索引鍵

MAXDOP = max_degree_of_parallelism

覆寫索引作業 組態選項 平行處理原則的最大程度。 如需詳細資訊,請參閱 設定 max degree of parallelism 伺服器組態選項。 使用 MAXDOP 來限制平行處理原則的程度,以及索引建置作業所產生的資源耗用量。

雖然所有 XML 索引和空間索引都支援語法 MAXDOP 選項,但 ALTER INDEX 目前只使用單一處理器。

max_degree_of_parallelism 可以是:

  • 1

    隱藏平行計劃產生。

  • >1

    根據目前的系統工作負載,將平行索引作業中使用的平行處理原則程度上限限製為指定的數位或更少。

  • 0 (預設值)

    除非根據目前的系統工作負載減少,否則使用伺服器、資料庫或工作負載群組層級所指定的平行處理原則程度。

如需詳細資訊,請參閱 設定平行索引作業。

注意

SQL Server 的所有版本都無法使用平行索引作業。 如需 SQL Server 版本支援的功能清單,請參閱 SQL Server 2022 的版本和支援功能

COMPRESSION_DELAY = { 0 | duration [ minutes ] }

適用於: SQL Server(從 SQL Server 2016 (13.x)開始)、Azure SQL Database 和 Azure SQL 受控實例

對於具有數據行存放區索引的磁碟數據表,指定關閉狀態的差異數據列群組必須保留在差異存放區中的最小分鐘數,資料庫引擎才能將它壓縮成壓縮的數據列群組。 由於磁碟數據表不會追蹤個別數據列的插入和更新時間,因此 Database Engine 只會將此延遲套用至處於關閉狀態的差異存放區數據列群組。

預設值是 0 分鐘。

如需何時使用 COMPRESSION_DELAY的建議,請參閱 開始使用數據行存放區,以取得實時作業分析

DATA_COMPRESSION

針對指定的索引、分割區編號或分割區範圍指定資料壓縮選項。 選項如下:

  • 不會壓縮索引或指定的資料分割。 這不適用於資料行存放區索引。

  • ROW

    使用資料列壓縮來壓縮索引或指定的分割區。 這不適用於資料行存放區索引。

  • PAGE

    使用頁面壓縮來壓縮索引或指定的分割區。 這不適用於資料行存放區索引。

  • COLUMNSTORE

    適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

    只適用於資料行存放區索引,包括非叢集資料行存放區索引和叢集資料行存放區索引。 指定 COLUMNSTORE 會移除所有其他資料壓縮,包括 COLUMNSTORE_ARCHIVE

  • COLUMNSTORE_ARCHIVE

    適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

    只適用於資料行存放區索引,包括非叢集資料行存放區索引和叢集資料行存放區索引。 COLUMNSTORE_ARCHIVE 進一步將指定的分割區壓縮為較小的大小。 這可用於封存,或是其他需要較小儲存體,而且可負擔更多時間來儲存和擷取的狀況。

如需壓縮的詳細資訊,請參閱資料壓縮 (機器翻譯)

XML_COMPRESSION

適用於:SQL Server 2022 (16.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

針對包含一或多個 xml 資料類型資料行的指定索引,指定 XML 壓縮選項。 選項如下:

  • ON

    使用 XML 壓縮來壓縮索引或指定的分割區。

  • OFF

    不會壓縮索引或指定的資料分割。

ON PARTITIONS ( { <partition_number_expression> | <range> } [ ,...n ] )

指定套用 DATA_COMPRESSIONXML_COMPRESSION 設定的分割區。 如果未分割索引,自 ON PARTITIONS 變數會產生錯誤。 如果未提供 ON PARTITIONS 子句,DATA_COMPRESSIONXML_COMPRESSION 選項會套用到資料分割索引的所有分割區。

可以使用下列方式來指定 <partition_number_expression>

  • 提供分割區的編號,例如:ON PARTITIONS (2)
  • 為數個個別分割區提供以逗號分隔的分割區編號,例如:ON PARTITIONS (1, 5)
  • 同時提供範圍和個別分割區:ON PARTITIONS (2, 4, 6 TO 8)

<range> 可以指定為以 TO字分隔的數據分割編號,例如:ON PARTITIONS (6 TO 8)

若要為不同的分割區設定不同類型的資料壓縮,請指定 DATA_COMPRESSION 選項一次以上,例如:

REBUILD WITH
(
DATA_COMPRESSION = NONE ON PARTITIONS (1),
DATA_COMPRESSION = ROW ON PARTITIONS (2, 4, 6 TO 8),
DATA_COMPRESSION = PAGE ON PARTITIONS (3, 5)
);

您也可以多次指定 XML_COMPRESSION 選項,例如:

REBUILD WITH
(
XML_COMPRESSION = OFF ON PARTITIONS (1),
XML_COMPRESSION = ON ON PARTITIONS (2, 4, 6 TO 8),
XML_COMPRESSION = OFF ON PARTITIONS (3, 5)
);

RESUME

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

繼續手動暫停的索引作業,因為達到最大持續時間,或因為失敗。

  • MAX_DURATION

    指定在重新暫停之前繼續之後,會執行可繼續索引作業的時間,以整數分鐘為單位。

  • WAIT_AT_LOW_PRIORITY

    暫停之後繼續索引建置作業必須取得必要的鎖定。 WAIT_AT_LOW_PRIORITY 表示索引建置作業會取得低優先順序鎖定,讓其他作業在索引建置作業等候時繼續。 省略 WAIT_AT_LOW_PRIORITY 選項相當於 WAIT_AT_LOW_PRIORITY (MAX_DURATION = 0 minutes, ABORT_AFTER_WAIT = NONE)。 如需詳細資訊,請參閱 WAIT_AT_LOW_PRIORITY

PAUSE

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

暫停可繼續的索引建置作業。

ABORT

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

中止已啟動為可繼續的執行或暫停的索引建置作業。 您必須明確地執行 ABORT 命令,以終止可繼續的索引建置作業。 可繼續索引作業中的失敗或暫停不會終止其執行;相反地,它會讓作業處於無限期暫停狀態。

備註

ALTER INDEX 無法用來重新分割索引,或將其移到另一個檔案群組。 您不能利用這個陳述式來修改索引定義,例如新增或刪除資料行,或變更資料行順序。 請搭配 CREATE INDEX 子句來使用 DROP_EXISTING,以執行這些作業。

未明確指定選項時,會套用目前的設定。 例如,如果未 FILLFACTORREBUILD 子句中指定設定,則會在重建程序期間使用儲存在系統目錄中的填滿因數值。 若要檢視目前的索引選項設定,請使用 sys.indexes

ONLINEMAXDOPSORT_IN_TEMPDB 的值並未儲存在系統目錄中。 除非索引陳述式中另有指定,否則會使用選項的預設值。

在多重處理器的電腦上,ALTER INDEX REBUILD 也如同其他查詢一樣,會自動使用更多處理器來執行與修改索引相關的掃描和排序作業。 相反地,ALTER INDEX REORGANIZE 是單個線程作業。 如需詳細資訊,請參閱 設定平行索引作業。

在 Microsoft Fabric 的 SQL 資料庫中, ALTER INDEX ALL 不支援 ,但 ALTER INDEX <index name> 為 。

重建索引

重建索引會卸除和重新建立索引。 這會移除片段;根據指定的或現有的填滿因數設定壓縮頁面來收回磁碟空間,以及重新排序連續頁面中的索引資料列。 指定 時 ALL ,數據表上的所有索引都會卸除,並在單一交易中重建。 不需要事先卸除外部索引鍵條件約束。 當重建含有 128 個 (含) 以上範圍的索引時,資料庫引擎會延遲實際的頁面解除配置及其相關聯的鎖定,直到認可交易之後。 如需詳細資訊,請參閱 延遲解除分配

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

重新組織索引

重新組織索引所用的系統資源最少。 它會實際重新排序分葉層級的頁面,使它們由左至右符合分葉節點的邏輯順序,以重新組織資料表和檢視表之叢集和非叢集索引的分葉層級。 重新組織也會壓縮索引頁面。 壓縮是以現有填滿因數值為基礎。

當指定 ALL 時,會重新組織資料表的叢集和非叢集關聯式索引及 XML 索引。 指定 ALL時,套用某些 限制。

如需詳細資訊,請參閱 優化索引維護以改善查詢效能並減少資源耗用量

注意

對於具有已排序數據行存放區索引的數據表,ALTER INDEX REORGANIZE 不會重新排序數據。 若要重新排序資料,請使用 ALTER INDEX REBUILD

停用索引

停用索引可防止使用者存取索引,如果是叢集索引,則可防止使用者存取基礎資料表的資料。 索引定義會保留在系統目錄中。 停用檢視的非叢集索引或叢集索引時,會實際刪除索引資料。 停用叢集索引可防止存取資料,資料仍會保留在 B 型樹狀目錄中,但不進行維護,直到卸除或重建索引為止。 若要查看索引是否已停用,請使用 sys.indexes 目錄檢視中的 [is_disabled] 資料行。

注意

文件通常會使用「B 型樹狀結構」一詞來指稱索引。 在資料列存放區索引中,資料庫引擎會實作 B+ 樹狀結構。 這不適用於資料行存放區索引或經記憶體最佳化的資料表。 如需詳細資訊,請參閱 SQL Server 和 Azure SQL 索引架構和設計指南

如果數據表位於事務複製發行集中,您無法停用與主鍵條件約束相關聯的索引。 複寫需要這些索引。 若要停用這類索引,您必須先從發行集卸除數據表。 如需詳細資訊,請參閱 發佈數據和資料庫物件。

使用 ALTER INDEX REBUILD 陳述式或 CREATE INDEX WITH DROP_EXISTING 陳述式來啟用索引。 重建已停用的叢集索引,無法使用設定為 ONLINE的選項來執行ON。 如需詳細資訊,請參閱 停用索引和條件約束

設定選項

您可以設定指定索引的選項 ALLOW_ROW_LOCKSALLOW_PAGE_LOCKSOPTIMIZE_FOR_SEQUENTIAL_KEYIGNORE_DUP_KEYSTATISTICS_NORECOMPUTE ,而不需重建或重新組織該索引。 修改的值會立即套用在索引上。 若要檢視這些設定,請使用 sys.indexes。 如需詳細資訊,請參閱 設定索引選項。

資料列和頁面鎖定選項

如果 ALLOW_ROW_LOCKS = ONALLOW_PAGE_LOCK = ON,當您存取索引時,允許資料列、頁面和資料表層級的鎖定。 資料庫引擎會選擇適當的鎖定,且可以將鎖定從資料列或頁面鎖定擴大到資料表鎖定。

如果 ALLOW_ROW_LOCKS = OFFALLOW_PAGE_LOCK = OFF,當您存取索引時,只允許資料表層級的鎖定。

如果在 ALL 設定數據列或頁面鎖定選項時指定,則設定會套用至所有索引。 當基礎資料表是堆積時,會依照下列方式來套用設定:

選項 適用於
ALLOW_ROW_LOCKS = ONOFF 堆積和所有相關聯的非叢集索引。
ALLOW_PAGE_LOCKS = ON 堆積和所有相關聯的非叢集索引。
ALLOW_PAGE_LOCKS = OFF 不允許所有頁面鎖定的非叢集索引。 針對堆積,不允許共用 (S)、更新 (U) 和獨佔 (X) 頁面鎖定。 資料庫引擎仍可取得意圖頁面鎖定(ISIUIX),以供內部使用。

警告

不建議停用索引上的數據列或頁面鎖定。 可能會發生並行相關問題,而且某些功能可能無法使用。 例如,當 ALLOW_PAGE_LOCKS 設定為 OFF時,就無法重新組織索引。

線上索引作業

重建索引,並將 [ONLINE] 選項設定為 ON,索引中的數據、其相關聯的數據表,以及相同數據表上的其他索引可供查詢和修改。 您也可以在線上重建位於單一分割區之索引的一部分。 在索引重建結束時,只有短暫的時間才會保留獨佔數據表鎖定。

索引一律是在線上重新組織。 此程式只會在短時間內保留鎖定,而且不太可能封鎖查詢或更新。

只有在執行下列作業時,才可以在相同的數據表或數據表分割區上執行並行在線索引作業:

  • 建立多個非叢集索引。
  • 在相同資料表上重新組織不同的索引。
  • 在重建相同資料表的非重疊索引時,重新組織不同的索引。

同時執行的所有其他線上索引作業都會失敗。 例如,您不能在相同資料表上,同時重建兩個或更多索引,或在相同資料表上重建現有索引時,建立新的索引。

如需詳細資訊,請參閱 在線執行索引作業。

可繼續的索引作業

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

您可以讓在線索引重建繼續。 這表示可以停止索引重建,稍後再從停止的點重新啟動。 若要以可繼續方式執行索引重建,請指定 [RESUMABLE = ON] 選項。

下列指導方針適用於可繼續的索引作業:

  • 若要使用 RESUMABLE 選項,您也必須使用 ONLINE 選項。
  • RESUMABLE 選項不會保存在指定索引的元數據中,而且僅適用於目前 DDL 語句的持續時間。 因此,必須明確指定 RESUMABLE = ON 子句,才能啟用可繼續性。
  • 您可以在兩個內容中指定 MAX_DURATION 選項:
    • RESUMABLE 選項的 MAX_DURATION 會指定所建置索引的時間間隔。 這段時間過後,如果索引組建仍在執行中,則會暫停。 您決定何時可以繼續建立暫停索引的組建。 MAX_DURATION時間 必須大於 0 分鐘,且小於或等於一周 (7 * 24 * 60 = 10080 分鐘)。 索引作業中的長時間暫停可能會明顯影響特定數據表上的 DML 效能,以及資料庫磁碟容量,因為原始索引和新建立的索引都需要磁碟空間,而且需要 DML 作業更新。 如果省略 MAX_DURATION 選項,索引作業會繼續直到完成或發生失敗為止。
    • WAIT_AT_LOW_PRIORITY 選項 MAX_DURATION 指定在採取動作之前,如果索引作業遭到封鎖,則等候使用低優先順序鎖定的時間。 如需詳細資訊,請參閱使用在線索引作業 WAIT_AT_LOW_PRIORITY
  • 若要立即暫停索引作業,您可以執行 ALTER INDEX PAUSE 命令,或執行 KILL <session_id> 命令。
  • 重新執行具有相同參數的原始 ALTER INDEX REBUILD 陳述式,就會繼續已暫停的索引重建作業。 您也可以執行 ALTER INDEX RESUME 陳述式,繼續已暫停的索引重建作業。
  • ABORT 命令會終止執行索引組建的會話,並取消索引作業。 您無法繼續已中止的索引作業。
  • 繼續暫停的索引重建作業時,您可以將 MAXDOP 值變更為新的值。 如果在繼續暫停的索引作業時未指定 MAXDOP,則會使用用於上一個繼續的 MAXDOP 值。 如果索引重建作業完全未指定 MAXDOP 選項,則會使用預設值。

可繼續的索引作業會執行,直到它完成、暫停或失敗為止。 如果作業暫停,則會發出錯誤,指出作業已暫停,且索引重建未完成。 如果作業失敗,也會發出錯誤。

若要查看索引作業是否以可繼續的作業的形式執行,以及檢查其目前的執行狀態,請使用 sys.index_resumable_operations 目錄檢視。

資源

可繼續索引作業需要下列資源:

  • 保留建置索引所需的額外空間,包括建置暫停的時間。
  • 排序階段期間的其他記錄輸送量。 相較於一般在線索引重建,可繼續索引的整體記錄空間使用量較低,而且允許在此作業期間截斷記錄。
  • 不允許在索引作業暫停時,嘗試修改正在重建的索引或其相關聯數據表的 DDL 語句。
  • 在作業暫停和作業執行期間,在組建內索引上封鎖准刪除清除。
  • 如果數據表包含 LOB 資料行,可繼續的叢集索引組建在作業開始時需要架構修改 (Sch-M) 鎖定。

目前的功能限制

可繼續的索引重建作業有下列限制:

  • 可繼續索引作業不支援 SORT_IN_TEMPDB = ON 選項。
  • 具有 RESUMABLE = ON 的 DDL 命令無法在明確交易內執行。
  • 您無法建立包含下列專案的可繼續索引:
    • 計算或 時間戳/rowversion 數據行作為索引鍵數據行。
    • LOB 資料行做為內含數據行。
  • 不支援可繼續的索引作業:
    • ALTER INDEX REBUILD ALL 命令
    • ALTER TABLE REBUILD 命令
    • 資料行存放區索引
    • 篩選的索引
    • 已停用的索引

WAIT_AT_LOW_PRIORITY 與線上索引作業

適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

當您不使用 [WAIT_AT_LOW_PRIORITY] 選項時,所有在數據表或索引上保留鎖定的作用中封鎖交易都必須完成,索引重建作業才能啟動和完成。 當在線索引作業開始且完成之前,它必須取得共用的(S)或架構修改(Sch-M)鎖定數據表,並加以保留一小段時間。 即使鎖定只保留一小段時間,也可能大幅影響工作負載輸送量、增加查詢延遲,或造成運行逾時。

為了避免這些問題,WAIT_AT_LOW_PRIORITY 選項可讓您管理在線索引作業啟動和完成所需的 SSch-M 鎖定行為,並從三個選項中選取。 在所有情況下,如果在 MAX_DURATION = n [minutes] 指定的等候時間期間,沒有牽涉到索引作業的封鎖,索引作業會立即繼續。

WAIT_AT_LOW_PRIORITY 讓在線索引作業使用低優先順序鎖定等候,讓其他作業同時使用一般優先順序鎖定繼續進行。 省略 WAIT_AT_LOW_PRIORITY 選項相當於 WAIT_AT_LOW_PRIORITY (MAX_DURATION = 0 minutes, ABORT_AFTER_WAIT = NONE)

MAX_DURATION = 時間 [MINUTES]

在線索引作業使用低優先順序鎖定等候的等候時間(以分鐘為單位指定的整數值)。 如果作業在一段時間內遭到 MAX_DURATION 封鎖,則會執行指定的 ABORT_AFTER_WAIT 動作。 MAX_DURATION 時間一律以分鐘為單位,而且可以省略該字 MINUTES

ABORT_AFTER_WAIT = [NONE | SELF | BLOCKERS ]

  • NONE:繼續等候具有正常優先順序的鎖定。
  • SELF:結束目前正在執行的在線索引作業,而不採取任何動作。 MAX_DURATION 為 0 時,無法使用選項 SELF
  • BLOCKERS:終止封鎖在線索引作業的所有使用者交易,讓作業可以繼續。 BLOCKERS 選項需要執行 CREATE INDEXALTER INDEX 語句的主體具有 ALTER ANY CONNECTION 許可權。

您可以使用下列擴充事件來監視以低優先順序等候鎖定的索引作業:

  • lock_request_priority_state
  • process_killed_by_abort_blockers
  • ddl_with_wait_at_low_priority

空間索引的限制

當您重建空間索引時,基礎用戶數據表在索引作業期間無法使用。

PRIMARY KEY 該數據表的數據行上定義空間索引時,無法修改用戶數據表中的條件約束。 若要變更 PRIMARY KEY 條件約束,請先卸除數據表的每個空間索引。 修改 PRIMARY KEY 條件約束之後,您可以重新建立每個空間索引。

在單一分割區重建作業中,您不能指定任何空間索引。 不過,您可以在數據表重建中指定空間索引。

若要變更空間索引特定的選項 (例如 BOUNDING_BOXGRID),您可以使用指定 CREATE SPATIAL INDEXDROP_EXISTING = ON 陳述式,或是卸除此空間索引並建立新的索引。 如需範例,請參閱 CREATE SPATIAL INDEX

資料壓縮

如需數據壓縮的詳細資訊,請參閱 數據壓縮

以下是使用數據壓縮時,索引建置作業內容中要考慮的重點:

  • 壓縮可以允許將更多數據列儲存在頁面上,但不會變更數據列大小上限。
  • 索引的非分葉頁面不是頁面壓縮,但可以數據列壓縮。
  • 每個非叢集索引都有個別的壓縮設定,而且不會繼承基礎表的壓縮設定。
  • 在堆積上建立叢集索引時,除非指定替代壓縮狀態,否則叢集索引會繼承堆積的壓縮狀態。

下列考慮會套用重建分割索引:

  • 如果數據表具有非對齊索引,則無法變更單一分割區的壓縮設定。
  • ALTER INDEX <index> ... REBUILD PARTITION ... WITH DATA_COMPRESSION = ... 語法會使用指定的壓縮選項重建索引的指定分割區。 如果省略 WITH DATA_COMPRESSION 子句,則會使用現有的壓縮選項。
  • ALTER INDEX <index> ... REBUILD PARTITION = ALL 語法會使用現有的壓縮選項重建索引的所有分割區。
  • ALTER INDEX <index> ... REBUILD PARTITION = ALL (WITH ...) 語法會重建此索引的所有分割區。 您可以使用 DATA_COMPRESSION = ... ON PARTITIONS ( ...) 子句,為不同的分割區選擇不同的壓縮。

若要評估變更 PAGEROW 壓縮如何影響數據表、索引或分割區,請使用 sp_estimate_data_compression_savings 預存程式。

統計資料

當您重建索引時,索引上的統計數據會以非數據分割索引的完整掃描進行更新,並使用數據分割索引的默認取樣比例進行更新。 數據表上沒有其他統計數據會更新為索引重建的一部分。

權限

需要數據表或檢視表 ALTER 許可權。

版本注意事項

  • Azure SQL Database 不支援 PRIMARY以外的檔案群組。
  • Azure SQL Database 和 Azure SQL 受控實例不支援 FILESTREAM 選項。
  • SQL Server 2012 (11.x) 之前無法使用資料行存放區索引。
  • SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例提供可繼續的索引作業。

基本語法範例

ALTER INDEX index1 ON table1 REBUILD;
ALTER INDEX ALL ON table1 REBUILD;
ALTER INDEX ALL ON dbo.table1 REBUILD;

範例:數據行存放區索引

這些範例適用於資料行存放區索引。

A. REORGANIZE 示範

此範例會示範 ALTER INDEX REORGANIZE 命令的運作方式。 會建立一個擁有多個資料列群組的資料表,然後示範 REORGANIZE 如何合併資料列群組。

-- Create a database
CREATE DATABASE [columnstore];
GO

-- Create a rowstore staging table
CREATE TABLE [staging] (
    AccountKey INT NOT NULL,
    AccountDescription NVARCHAR(50),
    AccountType NVARCHAR(50),
    AccountCodeAlternateKey INT
);

-- Insert 10 million rows into the staging table.
DECLARE @loop INT;
DECLARE @AccountDescription VARCHAR(50);
DECLARE @AccountKey INT;
DECLARE @AccountType VARCHAR(50);
DECLARE @AccountCode INT;

SELECT @loop = 0

BEGIN TRANSACTION

WHILE (@loop < 300000)
BEGIN
    SELECT @AccountKey = CAST(RAND() * 10000000 AS INT);
    SELECT @AccountDescription = 'accountdesc ' + CONVERT(VARCHAR(20), @AccountKey);
    SELECT @AccountType = 'AccountType ' + CONVERT(VARCHAR(20), @AccountKey);
    SELECT @AccountCode = CAST(RAND() * 10000000 AS INT);

    INSERT INTO staging
    VALUES (
        @AccountKey,
        @AccountDescription,
        @AccountType,
        @AccountCode
     );

    SELECT @loop = @loop + 1;
END

COMMIT

-- Create a table for the clustered columnstore index
CREATE TABLE cci_target (
    AccountKey INT NOT NULL,
    AccountDescription NVARCHAR(50),
    AccountType NVARCHAR(50),
    AccountCodeAlternateKey INT
);

-- Convert the table to a clustered columnstore index named inxcci_cci_target;
CREATE CLUSTERED COLUMNSTORE INDEX idxcci_cci_target ON cci_target;

使用 TABLOCK 選項來以平行處理方式插入資料列。 從 SQL Server 2016 (13.x)開始, INSERT INTO 使用 時 TABLOCK ,作業可以平行執行。

INSERT INTO cci_target WITH (TABLOCK)
SELECT TOP 300000 * FROM staging;

執行此命令以查看 OPEN 差異數據列群組。 資料列群組的數目取決於平行處理原則的程度。

SELECT *
FROM sys.dm_db_column_store_row_group_physical_stats
WHERE object_id  = object_id('cci_target');

執行此命令,強制所有數據CLOSEDOPEN列群組進入數據行存放區。

ALTER INDEX idxcci_cci_target ON cci_target REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

再次執行此命令,您會看到較小的數據列群組合並成一個壓縮的數據列群組。

ALTER INDEX idxcci_cci_target ON cci_target REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

B. 將關閉的差異資料列群組壓縮到資料行存放區中

這個範例會使用 REORGANIZE 選項,將每個 CLOSED 差異數據列群組壓縮到數據行存放區中,做為壓縮的數據列群組。 這並非必要,但當 Tuple-mover 無法快速壓縮 CLOSED 數據列群組時,這非常有用。

您可以在 AdventureWorksDW2022 範例資料庫中執行這兩個範例。

此範例會在所有分割區上執行 REORGANIZE

ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REORGANIZE;

此範例會在特定分割區上執行 REORGANIZE

-- REORGANIZE a specific partition
ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REORGANIZE PARTITION = 0;

C. 將所有開啟和關閉的差異資料列群組壓縮到資料行存放區中

適用於: SQL Server 2016 (13.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

命令 REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON) 會將每個 OPENCLOSED 差異數據列群組壓縮到數據行存放區中,做為壓縮的數據列群組。 這會清空差異存放區,並將所有資料列強制壓縮到資料行存放區。 這在執行許多插入作業之後特別有用,因為這些作業會將資料列儲存在一或多個差異資料行群組中。

REORGANIZE 結合數據列群組,以填滿最多數據列群組數目 <= 1,024,576。 因此,當您壓縮所有 OPENCLOSED 數據列群組時,最後不會包含許多只有少數數據列的壓縮數據列群組。 您可以將資料列群組盡量填滿,以縮小壓縮的大小並增進查詢效能。

下列範例使用 AdventureWorksDW2022 資料庫。

本範例會將所有 OPENCLOSED 差異數據列群組移至數據行存放區索引。

ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REORGANIZE WITH (COMPRESS_ALL_ROW_GROUPS = ON);

本範例會將所有 OPENCLOSED 差異數據列群組移至特定數據分割的數據行存放區索引。

ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REORGANIZE PARTITION = 0 WITH (COMPRESS_ALL_ROW_GROUPS = ON);

D. 線上重組資料行存放區索引

不適用於:SQL Server 2012 (11.x) 和 SQL Server 2014 (12.x)。

從 SQL Server 2016 (13.x) 開始, REORGANIZE 會比將差異數據列群組壓縮到數據行存放區還要多。 它也會執行線上重組。 首先,它會在資料列群組中 10% 或更多資料列已遭到刪除時,實際移除已刪除的資料列,以縮小資料行存放區大小。 然後,它會合併資料列群組以構成較大的資料列群組,每個資料列群組最多可包含 1,024,576 個資料列。 所有變更的資料列群組都會重新壓縮。

注意

從 SQL Server 2016 (13.x) 開始,在大部分情況下,重建數據行存放區索引已不再需要,因為 REORGANIZE 實際移除已刪除的數據列和合併數據列群組。 選項會將 COMPRESS_ALL_ROW_GROUPS 所有 OPENCLOSED 差異數據列群組強制到資料行存放區中,這些資料行存放區先前只能透過重建來完成。 REORGANIZE 在在線併發生在背景中,因此查詢可以在作業發生時繼續。

下列範例會 REORGANIZE 執行 ,藉由實際移除已從數據表中邏輯刪除的數據列,以及合併數據列群組,來重組索引。

ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REORGANIZE;

E. 離線重建叢集資料行存放區索引

適用於:SQL Server、Azure SQL Database 和 Azure SQL 受控實例

提示

從 2016 SQL Server 2016 (13.x) 和 Azure SQL Database 開始,我們建議針對資料行存放區索引使用 ALTER INDEX REORGANIZE 而不是 ALTER INDEX REBUILD

注意

在 SQL Server 2012 (11.x) 和 SQL Server 2014 (12.x) 中, REORGANIZE 僅用於將數據列群組壓縮 CLOSED 到數據行存放區。 若要執行重組作業並將所有差異資料列群組強制移動到資料行存放區,重建索引是唯一的方式。

此範例說明如何重建叢集資料行存放區索引,並將所有差異資料列群組強制移動到資料行存放區。 第一個步驟是在包含叢集資料行存放區索引的 FactInternetSales2 資料庫中準備 AdventureWorksDW2022 資料表,並插入前四個資料行的資料。

CREATE TABLE dbo.FactInternetSales2 (
    ProductKey [int] NOT NULL,
    OrderDateKey [int] NOT NULL,
    DueDateKey [int] NOT NULL,
    ShipDateKey [int] NOT NULL);

CREATE CLUSTERED COLUMNSTORE INDEX cci_FactInternetSales2
ON dbo.FactInternetSales2;

INSERT INTO dbo.FactInternetSales2
SELECT ProductKey, OrderDateKey, DueDateKey, ShipDateKey
FROM dbo.FactInternetSales;

SELECT * FROM sys.column_store_row_groups;

結果會顯示一個 OPEN 數據列群組,這表示 SQL Server 會在關閉資料列群組並將數據移至數據行存放區之前,等候新增更多數據列。 下一個陳述式會重建叢集資料行存放區索引,這會將所有資料列強制移動到資料行存放區中。

ALTER INDEX cci_FactInternetSales2 ON FactInternetSales2 REBUILD;
SELECT * FROM sys.column_store_row_groups;

語句的結果會顯示數據列群組為 SELECT,這表示數據列群組的數據COMPRESSED行區段現在會壓縮並儲存在數據行存放區中。

F. 離線重建叢集資料行存放區索引的分割區

適用於:SQL Server 2012 (11.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

若要重建大型叢集資料行存放區索引的分割區,請使用 ALTER INDEX REBUILD 與分割區選項。 這個範例會重建分割區 12。 從 SQL Server 2016 (13.x) 開始,我們建議將 REBUILD 取代為 REORGANIZE

ALTER INDEX cci_fact3
ON fact3
REBUILD PARTITION = 12;

G. 變更叢集資料行存放區索引以使用封存壓縮

不適用於:SQL Server 2012 (11.x)

您可以選擇使用 COLUMNSTORE_ARCHIVE 資料壓縮選項,進一步減少叢集數據行存放區索引的大小。 這項功能非常適合用於想要保存在較便宜儲存裝置上的較舊資料。 建議您只在不常存取的數據上使用這個值,因為解壓縮速度比一般 COLUMNSTORE 壓縮慢。

下列範例會重建叢集資料行存放區索引來使用封存壓縮,然後示範如何移除封存壓縮。 最終結果只會使用數據行存放區壓縮。

首先,建立具有叢集資料行存放區索引的資料表,以準備範例。 然後,使用封存壓縮進一步壓縮資料表。

--Prepare the example by creating a table with a clustered columnstore index.
CREATE TABLE SimpleTable (
    ProductKey [int] NOT NULL,
    OrderDateKey [int] NOT NULL,
    DueDateKey [int] NOT NULL,
    ShipDateKey [int] NOT NULL
);

CREATE CLUSTERED INDEX cci_SimpleTable ON SimpleTable (ProductKey);

CREATE CLUSTERED COLUMNSTORE INDEX cci_SimpleTable
ON SimpleTable
WITH (DROP_EXISTING = ON);

--Compress the table further by using archival compression.
ALTER INDEX cci_SimpleTable ON SimpleTable
REBUILD
WITH (DATA_COMPRESSION = COLUMNSTORE_ARCHIVE);
GO

此範例會移除封存壓縮,並且只使用資料行存放區壓縮。

ALTER INDEX cci_SimpleTable ON SimpleTable
REBUILD
WITH (DATA_COMPRESSION = COLUMNSTORE);
GO

範例:資料列存放區索引

A. 重建索引

下列範例會在 Employee 資料庫的 AdventureWorks2022 資料表上重建單一索引。

ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee REBUILD;

B. 在資料表上重建所有索引以及指定選項

下列範例會指定 關鍵字 ALL。 這會重建與 Production.Product 資料庫中 AdventureWorks2022 資料表相關聯的所有索引。 指定三個選項。

ALTER INDEX ALL ON Production.Product
REBUILD WITH (FILLFACTOR = 80, SORT_IN_TEMPDB = ON, STATISTICS_NORECOMPUTE = ON);

下列範例會加入包括低優先權鎖定選項的 ONLINE 選項,並加入資料列壓縮選項。

適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

ALTER INDEX ALL ON Production.Product
REBUILD WITH
(
    FILLFACTOR = 80,
    SORT_IN_TEMPDB = ON,
    STATISTICS_NORECOMPUTE = ON,
    ONLINE = ON ( WAIT_AT_LOW_PRIORITY ( MAX_DURATION = 4 MINUTES, ABORT_AFTER_WAIT = BLOCKERS ) ),
    DATA_COMPRESSION = ROW
);

C. 重新組織具有 LOB 壓縮的索引

下列範例會重新組織 AdventureWorks2022 資料庫中的單一叢集索引。 由於索引在分葉層級中包含 LOB 資料類型,因此,這個陳述式也會壓縮包含大型物件資料的所有頁面。 因為預設值為 ON,所以不需要指定 WITH (LOB_COMPACTION = ON) 選項。

ALTER INDEX PK_ProductPhoto_ProductPhotoID ON Production.ProductPhoto REORGANIZE WITH (LOB_COMPACTION = ON);

D. 設定索引上的選項

下列範例會設定 AK_SalesOrderHeader_SalesOrderNumber 資料庫中 AdventureWorks2022 索引的幾個選項。

ALTER INDEX AK_SalesOrderHeader_SalesOrderNumber ON
    Sales.SalesOrderHeader
SET (
    STATISTICS_NORECOMPUTE = ON,
    IGNORE_DUP_KEY = ON,
    ALLOW_PAGE_LOCKS = ON
    ) ;
GO

E. 停用索引

下列範例會停用 Employee 資料庫中 AdventureWorks2022 資料表的非叢集索引。

ALTER INDEX IX_Employee_ManagerID ON HumanResources.Employee DISABLE;

F. 停用條件約束

下列範例會PRIMARY KEY藉由停用資料庫中的PRIMARY KEYAdventureWorks2022索引來停用條件約束。 基礎 FOREIGN KEY 表的條件約束會自動停用,並顯示警告訊息。

ALTER INDEX PK_Department_DepartmentID ON HumanResources.Department DISABLE;

結果集會傳回這則警告訊息。

Warning: Foreign key 'FK_EmployeeDepartmentHistory_Department_DepartmentID'
on table 'EmployeeDepartmentHistory' referencing table 'Department'
was disabled as a result of disabling the index 'PK_Department_DepartmentID'.

G. 啟用條件約束

下列範例會啟用範例 F 中已停用的 PRIMARY KEYFOREIGN KEY 條件約束。

PRIMARY KEY 由重建 PRIMARY KEY 索引來啟用條件約束。

ALTER INDEX PK_Department_DepartmentID ON HumanResources.Department REBUILD;

FOREIGN KEY然後會啟用條件約束。

ALTER TABLE HumanResources.EmployeeDepartmentHistory
CHECK CONSTRAINT FK_EmployeeDepartmentHistory_Department_DepartmentID;
GO

H. 重建資料分割索引

下列範例會重建 5 資料庫中分割區索引 IX_TransactionHistory_TransactionDate 的單一分割區,分割區編號是 AdventureWorks2022。 分割區 5 在 ONLINE=ON 重建,而且低優先權鎖定的 10 分鐘等候時間會分別套用至索引重建作業取得的每一個鎖定。 如果在此時間無法取得鎖定來完成索引重建,則會由於 ABORT_AFTER_WAIT = SELF 導致重建作業陳述式本身中止。

適用於:SQL Server 2014 (12.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

-- Verify the partitioned indexes.
SELECT *
FROM sys.dm_db_index_physical_stats (DB_ID(),OBJECT_ID(N'Production.TransactionHistory'), NULL , NULL, NULL);
GO
--Rebuild only partition 5.
ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5
   WITH (ONLINE = ON (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 10 minutes, ABORT_AFTER_WAIT = SELF)));
GO

I. 變更索引的壓縮設定

下列範例會在非分割資料列存放區資料表上重建索引。

ALTER INDEX IX_INDEX1
ON T1
REBUILD
WITH (DATA_COMPRESSION = PAGE);
GO

J. 使用 XML 壓縮變更索引的設定

適用於:SQL Server 2022 (16.x) 和更新版本、Azure SQL 資料庫,以及 Azure SQL 受控執行個體。

下列範例會在非分割資料列存放區資料表上重建索引。

ALTER INDEX IX_INDEX1
ON T1
REBUILD
WITH (XML_COMPRESSION = ON);
GO

如需更多數據壓縮範例,請參閱 數據壓縮

K. 線上可繼續的索引重建

適用於:SQL Server 2017 (14.x) 和更新版本、Azure SQL Database 和 Azure SQL 受控實例

以下範例說明如何使用線上可繼續的索引重建。

使用 MAXDOP = 1執行在線索引重建作為可繼續的作業。 在索引作業暫停之後,再次執行相同的命令,會自動繼續索引重建作業。

ALTER INDEX test_idx on test_table REBUILD WITH (ONLINE = ON, MAXDOP = 1, RESUMABLE = ON);

執行在線索引重建作為可繼續的作業,並將 MAX_DURATION 設定為 240 分鐘。

ALTER INDEX test_idx on test_table REBUILD WITH (ONLINE = ON, RESUMABLE = ON, MAX_DURATION = 240);

暫停執行中的可繼續的線上索引重建。

ALTER INDEX test_idx on test_table PAUSE;

針對執行為可繼續作業的索引重建繼續在線索引重建,並指定設定為4的新值 MAXDOP

ALTER INDEX test_idx on test_table RESUME WITH (MAXDOP = 4);

繼續索引線上重建 (以可繼續的方式執行) 的線上索引重建作業。 設定 MAXDOP 為 2,將執行索引的運行時間設定為可繼續 240 分鐘,如果鎖定上封鎖索引,請等候 10 分鐘,並在之後終止所有封鎖程式。

ALTER INDEX test_idx on test_table
    RESUME WITH (MAXDOP = 2, MAX_DURATION = 240 MINUTES,
    WAIT_AT_LOW_PRIORITY (MAX_DURATION = 10, ABORT_AFTER_WAIT = BLOCKERS));

中止正在執行或暫停的可繼續索引重建作業。

ALTER INDEX test_idx on test_table ABORT;