CREATE JSON INDEX (Transact-SQL)

適用於: SQL Server 2025 (17.x) Azure SQL DatabaseAzure SQL 受控執行個體Microsoft Fabric 中的 SQL 資料庫

在指定的資料表和欄位上建立 JSON 索引。

JSON 索引:

  • 可以在數據表中有數據之前建立。
  • 可以藉由指定限定的資料庫名稱,在另一個資料庫中的數據表上建立。
  • 要求數據表具有叢集主鍵。
  • 無法在索引檢視表上指定。

Transact-SQL 語法慣例

語法

CREATE JSON INDEX name ON table_name (json_column_name)
  [ FOR ( sql_json_path [ , ...n ] ) ]
  [ WITH ( <json_index_option> [ , ...n ] ) ]
  [ ON { filegroup_name | "default" } ]
[ ; ]

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

<sql_json_path> ::=
    { character_string_literal }

<json_index_option> ::=
{
    OPTIMIZE_FOR_ARRAY_SEARCH = { ON | OFF }
  | FILLFACTOR = fillfactor
  | DROP_EXISTING = { ON | OFF }
  | ONLINE = OFF
  | ALLOW_ROW_LOCKS = { ON | OFF }
  | ALLOW_PAGE_LOCKS = { ON | OFF }
  | MAXDOP = max_degree_of_parallelism
  | DATA_COMPRESSION = { NONE | ROW | PAGE }
}

論點

索引名稱

索引的名稱。 索引名稱在數據表內必須是唯一的,但不需要在資料庫中是唯一的。 索引名稱必須遵循 識別碼的規則。

  • ON <物件> (json_column_name)

    指定要建立索引的物件(資料庫、架構或數據表),以及 json 數據行的名稱。

  • json_column_name

    中 table_name 數據類型的數據行名稱,其中包含零個或多個指定的 SQL/JSON 路徑。

  • sql_json_path

    需要從 json_column_name擷取和編製索引的 SQL/JSON 路徑。 sql_json_path 的預設值為 $。

    • 遞迴地索引指定路徑及其後續的所有鍵/值。
    • 在 JSON 檔路徑中支援最多 128 個層級。
    • 不允許重疊。

    例如, $.a 並 $.a.b 引發錯誤,因為路徑 $.a 遞歸包含所有路徑,且使用者意圖尚不清楚。

在filegroup_name上

在指定的檔案群組上建立指定的索引。 如果未指定任何位置且數據表未分割,索引會使用與基礎表相同的檔案群組。 檔案群組必須已經存在。

ON “default”

在預設檔案群組上建立指定的索引。

在此內容中,預設字詞不是關鍵詞。 它是預設檔案群組的識別碼,並必須以分隔符號括起,例如 ON "default" 或 ON [default]。 如果 "default" 已指定,則 QUOTED_IDENTIFIER 選項必須是 ON 目前會話的選項。 這是預設設定。 如需詳細資訊,請參閱SET QUOTED_IDENTIFIER。

<object>:: =

要編製索引的完整定義或非完整定義的物件。

  • database_name

    資料庫的名稱。

  • schema_name

    資料表所屬的結構描述名稱。

  • table_name

    要編製索引之數據表的名稱。

OPTIMIZE_FOR_ARRAY_SEARCH = { 在 |關閉 }

指定是否在 JSON 索引中最佳化陣列搜尋。 預設值為 OFF。

填充係數 = 填充係數

指定百分比,以表示 資料庫引擎 在索引建立或重建期間應該將每個索引頁面的分葉層級填滿的程度。 fillfactor 必須是從 1 到 的 100整數值。 預設值為 0。 如果 fillfactor 為 100 或 0,資料庫引擎 會建立索引,將分頁頁面填滿至容量上限。

備註

填滿因數值 0 和 100 在所有方面都相同。

只有在建立或重新編製索引時才會套用 FILLFACTOR 設定。 資料庫引擎不會動態保留頁面中空白空間的指定百分比。 若要檢視填滿因數設定,請使用 sys.indexes 目錄檢視。

建立叢集索引 FILLFACTOR 的小於 100 會影響數據佔用的儲存空間量,因為資料庫引擎會在建立叢集索引時重新發佈數據。

如需詳細資訊,請參閱 指定索引的填滿因素。

DROP_EXISTING = { ON |OFF }

指定捨棄並重建已命名的預先存在的 JSON 索引。 預設值為 OFF。

  • 開啟

    現有的索引會卸除並重建。 指定的索引名稱必須與目前現有的索引相同;不過,可以修改索引定義。 例如,您可以指定不同的資料行、排序順序、數據分割配置或索引選項。

  • OFF

    如果指定的索引名稱已經存在,就會顯示錯誤。

無法使用DROP_EXISTING來變更索引類型。

在線上 = 關閉

指定在索引作業期間,基礎表和相關聯的索引無法用於查詢和數據修改。 在此版本的 SQL Server 中,JSON 索引不支援在線索引組建。 如果這個選項設定 ON 為 JSON 索引,就會引發錯誤。 省略 ONLINE 選項或設定 ONLINE 為 OFF。

建立、重建或卸除 JSON 索引的離線索引作業,會取得資料表上的架構修改 (Sch-M) 鎖定。 這可防止所有使用者在作業持續期間存取基礎資料表。

SQL Server 的每個版本都無法使用在線索引作業。

如需查看 Windows 上各版本 SQL Server 所支援的功能清單,請參閱:

ALLOW_ROW_LOCKS = { ON |OFF }

指定是否允許數據列鎖定。 預設值為 ON。

  • 開啟

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

  • OFF

    不會使用資料列鎖定。

ALLOW_PAGE_LOCKS = { ON |OFF }

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

  • 開啟

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

  • OFF

    不會使用頁面鎖定。

MAXDOP = max_degree_of_parallelism

覆蓋索引作業期間的 max degree of parallelism 組態選項。 使用 MAXDOP 來限制平行計劃執行中使用的處理器數目。 最大值為64個處理器。

這很重要

雖然MAXDOP選項在語法上受到支援,但CREATE JSON INDEX目前只使用單一處理器。

max_degree_of_parallelism 可以是下列其中一個值。

價值觀 說明
1 抑制平行計劃方案的生成。
>1 根據目前的系統工作負載,將平行索引作業所使用的處理器數目上限,限制為所指定的數目或更少的數目。
0 (預設值) 根據目前的系統工作負載,使用實際數目或比實際數目更少的處理器。

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

SQL Server 的所有版本都無法使用平行索引作業。

如需查看 Windows 上各版本 SQL Server 所支援的功能清單,請參閱:

DATA_COMPRESSION = { NONE |ROW |PAGE }

決定索引所使用的數據壓縮層級。

  • 沒有

    索引未對數據使用任何壓縮

  • 列

    索引使用於數據的資料列壓縮

  • 頁

    使用於數據索引的頁面壓縮

備註

每個選項只能為每個 CREATE JSON INDEX 語句指定一次。 指定任何重覆選項會引發錯誤。

[ ON { filegroup_name |“default” } ]

如果您指定 JSON 索引的檔案群組,則不論數據表的數據分割配置為何,索引都會放在該檔案群組上。

欲了解更多關於建立索引的資訊,請參閱 中的 CREATE INDEX備註區。

JSON 索引支援的述詞

如果 JSON 索引存在於 json 數據行上,則可以優化數據表中 JSON 數據行中包含的 JSON 檔搜尋作業。 JSON 索引用於具有各種 JSON 函式表示式的查詢中。

下列範例使用資料庫中的 Sales.SalesOrderHeader 表格,其中有一個名為 AdventureWorks2025 的 json 欄位。 Info 欄會建立為 json 類型。 JSON 索引也會在 Info 數據行上,以預設設定建立。 下列程式代碼範例顯示 CREATE JSON INDEX 語句:

CREATE JSON INDEX sales_info_idx
    ON Sales.SalesOrderHeader (Info);

針對範例搜尋表示式,請使用下列 JSON 檔作為數據:

銷售訂單號碼 資訊
437 {"Customer":{"Name":"Kelsey Raje","ID":16517,"Type":"IN"},"Order":{"ID":43710,"Number":"SO43710","CreationDate":"2011-06-02T00:00:00","TotalDue":3953.9884}}
643 {"Customer":{"Name":"Aaron Campbell","ID":16167,"Type":"IN"},"Order":{"ID":64304,"Number":"SO64304","CreationDate":"2014-01-16T00:00:00","TotalDue":36.0230, "IsProcessed": true}}

JSON_PATH_EXISTS函式

使用 JSON_PATH_EXISTS 函式來測試 JSON 檔中是否有指定的 SQL/JSON 路徑。

此查詢示範 JSON_PATH_EXISTS 可在 JSON 數據行上使用 JSON 索引進行優化:

SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE JSON_PATH_EXISTS(Info, '$.Order.IsProcessed') = 1;

JSON 索引支援 JSON_PATH_EXISTS 述詞和下列運算符:

  • 比較運算子 (=)
  • IS [NOT] NULL 述詞(目前不支援)

JSON_VALUE函式

使用 JSON_VALUE ,在 JSON 檔中擷取指定 SQL/JSON 路徑中的 JSON 文字/純量值。 下列查詢顯示如何使用 JSON_VALUE JSON 索引優化 json 資料行上的表達式。

  • 在物件屬性中檢查 JSON 字串的相等性:

    SELECT COUNT(*)
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.Type') = 'IN';
    
  • 將值轉換為 int 資料類型後,檢查物件屬性中的 JSON 數字是否相等。

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.ID' RETURNING INT) = 16167;
    
  • 將 JSON 數字轉換為 int 資料類型後,於物件屬性中進行範圍搜尋:

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Customer.ID' RETURNING INT) IN (16167, 16517);
    
  • 在將值轉換成 十進位 數據類型之後,範圍搜尋 JSON 數字於物件屬性中:

    SELECT *
    FROM Sales.SalesOrderHeader
    WHERE JSON_VALUE(Info, '$.Order.TotalDue RETURNING decimal(20, 4)) BETWEEN 1000 and 2000;
    

JSON 索引支援 JSON_VALUE 述詞,以及下列運算子:

  • 比較運算子 (=)
  • LIKE 謂詞(尚未支援)
  • IS [NOT] NULL 謂詞(尚未支援)

JSON_CONTAINS函式

JSON_CONTAINS函式支援在 JSON 檔中輕鬆搜尋 JSON 值,如果 JSON 資料行上存在,可以使用 JSON 索引。 此函式可用來測試 JSON 純量值、物件或數位是否包含在 JSON 檔中的指定 SQL/JSON 路徑中。 指定為 SQL 純量類型的搜尋值會根據現有的 SQL/JSON 類型轉換來轉換。 這些規則定義於行為區段中。

要求

包含 JSON 資料行的數據表上需要叢集索引鍵。 如果叢集索引鍵不存在,就會引發錯誤。 叢集索引鍵限制為31個數據行,索引鍵的大小上限應小於128個字節。

權限

用戶必須在該數據表上具有 ALTER 權限,或是 sysadmin 固定伺服器角色的成員,或者是 db_ddladmin 和 db_owner 固定資料庫角色的成員。

局限性

JSON 索引語句存在下列限制:

  • 數據表中的 json 數據行上只能建立一個 JSON 索引。
  • 您可以在資料表中建立最多 249 個 JSON 索引。 不支援在特定 JSON 數據行上建立多個 JSON 索引。
  • 無法在計算的 json 數據行上建立 JSON 索引。
  • 無法在檢視表、表值變數或記憶體優化表的 JSON 列上建立索引。
  • JSON 索引只能以離線方式建立或變更。
  • JSON 路徑無法在索引定義中重疊。 例如,$a 和 $a.b 重疊,不允許在 CREATE JSON INDEX 語句中。
  • 修改路徑需要重新建立 JSON 索引。
  • 索引提示不支援 JSON 索引。
  • 不支援數據壓縮選項。

範例

A。 在 JSON 數據行上建立 JSON 索引

下列範例會建立名為 docs 的數據表,其中包含 json 類型資料行 content。 此範例然後會在 json_content_index 資料行上建立 JSON 索引 content。 此範例會在 JSON 檔中的整個 JSON 檔或所有 SQL/JSON 路徑上建立 JSON 索引。

DROP TABLE IF EXISTS docs;

CREATE TABLE docs
(
    content JSON,
    id INT PRIMARY KEY
);

CREATE JSON INDEX json_content_index
    ON docs (content);

A。 在具有特定路徑的 JSON 數據行上建立 JSON 索引

下列範例會建立名為 docs 的數據表,其中包含 json 類型資料行 content。 此範例然後會在 json_content_index 資料行上建立 JSON 索引 content。 此範例會在 JSON 檔中的特定 SQL/JSON 路徑上建立 JSON 索引。
這個範例也會將索引 FILLFACTOR 設定為 80。

DROP TABLE IF EXISTS docs;

CREATE TABLE docs
(
    content JSON,
    id INT PRIMARY KEY
);

CREATE JSON INDEX json_content_index
    ON docs (content)
    FOR ('$.a', '$.b') WITH (FILLFACTOR = 80);

B. 具有陣列搜尋最佳化的 JSON 索引

下列範例會傳回資料表 dbo.Customers的 JSON 索引。 JSON 索引是在啟用陣列搜尋最佳化選項的情況下建立的。

DROP TABLE IF EXISTS dbo.Customers;

CREATE TABLE dbo.Customers
(
    customer_id INT IDENTITY PRIMARY KEY,
    customer_info JSON NOT NULL
);

CREATE JSON INDEX CustomersJsonIndex
    ON dbo.Customers (customer_info) WITH (OPTIMIZE_FOR_ARRAY_SEARCH = ON);

INSERT INTO dbo.Customers (customer_info)
VALUES ('{"name":"customer1", "email": "customer1@example.com", "phone":["123-456-7890", "234-567-8901"]}');

SELECT object_id,
       index_id,
       optimize_for_array_search
FROM sys.json_indexes AS ji
WHERE object_id = OBJECT_ID('dbo.Customers');