适用于: SQL Server 2025 (17.x) 预览版
在 SQL Server 2025 (17.x) 预览版中的指定表和列上创建 JSON 索引。
JSON 索引:
- 可以在表中有数据之前创建。
- 可以通过指定限定的数据库名称在另一个数据库中的表上创建。
- 要求表具有聚簇主键。
- 不能在索引视图上指定。
注释
创建 JSON 索引目前为预览版,仅在 SQL Server 2025(17.x) 预览版中可用。
语法
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> ::=
{
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
包含零个或多个指定 SQL/JSON 路径的 json 数据类型
table_name
列的名称。sql_json_path
需要从
json_column_name
中提取和编制索引的 SQL/JSON 路径。sql_json_path
的默认值是$
。- 以递归方式从指定路径开始为所有键/值编制索引。
- JSON 文档路径中最多支持 128 个级别。
- 不允许重叠。
例如,
$.a
并$.a.b
引发错误,因为路径$.a
以递归方式包括所有路径,并且用户意图尚不清楚。
ON filegroup_name
为指定文件组创建指定索引。 如果未指定任何位置且未对表进行分区,索引将使用与基础表相同的文件组。 文件组必须已存在。
在“默认”上
在默认文件组上创建指定的索引。
在此上下文中,术语默认值不是关键字。 它是默认文件组的标识符,必须按 In 或 in ON "default"
或 ON [default]
. 如果 "default"
已指定,则 QUOTED_IDENTIFIER
选项必须为 ON
当前会话。 这是默认设置。 有关详细信息,请参阅 SET QUOTED_IDENTIFIER。
<object>:: =
需要索引的对象可以是完全限定或非完全限定的。
database_name
数据库的名称。
schema_name
表所属的架构的名称。
table_name
要编制索引的表的名称。
FILLFACTOR = fillfactor
指定一个百分比,指示在数据库引擎创建或重新生成索引的过程中,应将每个索引页面的叶级填充到什么程度。
fillfactor 必须是一个从 1
到 100
的整数值。 默认值为 0
。 如果 fillfactor 为 100
或 0
,则数据库引擎会创建索引,其中叶页被填满至容量。
注释
填充因子值 0
和 100
在各个方面都是相同的。
FILLFACTOR
设置仅在创建或重新生成索引时应用。 数据库引擎并不会在页中动态保持指定的可用空间百分比。 若要查看填充因子设置,请使用 sys.indexes 目录视图。
创建一个FILLFACTOR
小于100
的聚集索引会影响数据占用的存储空间量,因为数据库引擎在创建聚集索引时会重新分发数据。
有关详细信息,请参阅 为索引指定填充因子。
DROP_EXISTING = { ON |OFF }
指定删除并重新生成已存在的命名空间索引。 默认值为 OFF
。
开
删除现有索引并重新生成。 指定的索引名称必须与当前现有索引相同;但是,可以修改索引定义。 例如,可以指定不同的列、排序顺序、分区方案或索引选项。
OFF
如果指定的索引名称已存在,则会显示错误。
无法使用 DROP_EXISTING
更改索引类型。
ONLINE = OFF
指定基础表和关联的索引在索引作期间不能用于查询和数据修改。 在此版本的 SQL Server 中,JSON 索引不支持联机索引生成。 如果此选项设置为 ON
JSON 索引,则会引发错误。 省略选项 ONLINE
或设置为 ONLINE
OFF
.
离线索引操作在创建、重建或删除 JSON 索引时,会获取表上的架构修改(Sch-M)锁。 这样可以防止所有用户在操作期间访问基础表。
在 SQL Server 中,并不是每个版本都支持联机索引操作。
有关 Windows 上 SQL Server 各版本支持的功能列表,请参阅:
- SQL Server 2025 预览版的版本和支持的功能
- SQL Server 2022 各个版本及其支持的功能
- SQL Server 2019 各个版本及其支持的功能
- 版本和 SQL Server 2017 支持的功能
- 版本和 SQL Server 2016 支持的功能
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 SPATIAL INDEX
但目前始终只使用单个处理器。
max_degree_of_parallelism 可以是以下值之一。
价值 | DESCRIPTION |
---|---|
1 |
取消生成并行计划。 |
>1 |
基于当前系统工作负荷,将并行索引操作中使用的最大处理器数限制为指定数量或更少。 |
0 (默认值) |
根据当前系统工作负荷使用实际的处理器数量或更少数量的处理器。 |
有关详细信息,请参阅 “配置并行索引作”。
并行索引操作并不适用于 SQL Server 的所有版本。
有关 Windows 上 SQL Server 各版本支持的功能列表,请参阅:
- SQL Server 2025 预览版的版本和支持的功能
- SQL Server 2022 各个版本及其支持的功能
- SQL Server 2019 各个版本及其支持的功能
- 版本和 SQL Server 2017 支持的功能
- 版本和 SQL Server 2016 支持的功能
DATA_COMPRESSION = { NONE |ROW |PAGE }
确定索引使用的数据压缩级别。
没有
索引未对数据使用压缩
排
索引对数据使用的行压缩
页
索引对数据使用的页面压缩
注解
每个选项只能为每个 CREATE JSON INDEX
语句指定一次。 指定重复任意一个选项将会引发错误。
[ ON { filegroup_name |“default” } ]
如果为 JSON 索引指定文件组,则无论表的分区方案如何,索引都会放置在该文件组上。
有关创建索引的详细信息,请参阅 CREATE INDEX 中的“备注”部分。
JSON 索引支持的谓词
如果 JSON 列上存在一个 JSON 索引,则可以优化在表中 JSON 列中包含的 JSON 文档上的搜索操作。 JSON 索引用于各种基于 JSON 函数表达式的查询。
以下示例使用AdventureWorks2022
数据库中的Sales.SalesOrderHeader
表以及名为Info
的json列。 将 Info
列创建为 json 类型。 还会在具有默认设置的 Info
列上创建 JSON 索引。 下面的代码示例演示了 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 索引来优化 JSON_PATH_EXISTS
列:
SELECT COUNT(*)
FROM Sales.SalesOrderHeader
WHERE JSON_PATH_EXISTS(Info, '$.Order.IsProcessed') = 1;
谓词和以下运算符支持 JSON_PATH_EXISTS
JSON 索引:
- 比较运算符 (
=
) -
IS [NOT] NULL
谓词 (当前不支持)
JSON_VALUE函数
使用 JSON_VALUE 提取 JSON 文档中指定 SQL/JSON 路径中的 JSON 文本/标量值。 以下查询演示了如何使用 JSON 索引来优化 json 列中的 JSON_VALUE
表达式。
在对象属性中搜索 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;
将值转换为 int 数据类型后,范围搜索对象属性中的 JSON 编号:
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 文档中指定的 SQL/JSON 路径中是否包含 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 索引只能以脱机方式创建或更改。
- JSON 路径不能在索引定义中重叠。 例如,
$a
和$a.b
重叠,不允许在CREATE JSON INDEX
语句中。 - 修改路径需要重新创建 JSON 索引。
- 索引提示不支持 JSON 索引。
- 不支持数据压缩选项。
例子
答: 在 JSON 列上创建 JSON 索引
以下示例创建一个名为包含 docs
类型列的表content
。 然后,该示例在content
列上创建 JSON 索引json_content_index
。 该示例针对 JSON 文档的整个 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);
答: 在具有特定路径的 JSON 列上创建 JSON 索引
以下示例创建一个名为包含 docs
类型列的表content
。 然后,该示例在列content
上创建 JSON 索引json_content_index
。 此示例在 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);