全部产品
Search
文档中心

云原生数据库 PolarDB:列存索引JSON索引

更新时间:Aug 27, 2026

当JSON列的查询需要解析整个JSON数据时,列存索引(IMCI)提供JSON索引功能,通过JSON分词器将JSON数据拆解并构建为倒排索引,避免加载和解析完整JSON对象,提升json_overlaps、json_contains、json_extract、json_unquote、json_type、json_length、json_keys与json_depth等表达式的查询效率。

说明

列存索引JSON索引目前处于灰度阶段,若您有相关需求,请提交工单联系我们为您处理。

创建JSON索引

JSON索引通过JSON分词器将JSON对象拆解出数组项或键值对并添加到倒排索引,查询时直接通过索引判断是否命中,避免加载和解析整个JSON对象。JSON索引仅支持JSON类型的列,包含三种索引类型:

  • JSON数组索引(mode=0 或 mode=1):用于数组类型的JSON列,仅支持标量数组(即数组元素为整型、字符串或时间等),不适用于对象数组或嵌套数组;建议使用 mode=1。可用于 json_overlaps 与 json_contains。

  • JSON键值索引(mode=2):用于对象类型的JSON列,且键值对的值类型为标量(即整型、字符串或时间等)或标量数组。通过json_paths参数指定需要索引的键或数组,如 {$.k1}、{$[*].k1,$[*].k2} 等。可用于 json_extract、json_overlaps 与 json_contains。

  • JSON混合索引(mode=3):用于任何类型的JSON列,且键值对的值类型为标量、对象、标量数组或对象数组。通过 json_paths 参数指定需要索引的键或数组,path 后面可带 @[extract|contains|overlaps|unquote|type|length|keys|depth|structure_path|structure_hash|structure_value] 表示支持哪些表达式:默认为 @[extract|contains|overlaps],表示支持 json_overlaps、json_contains 与 json_extract 等标量或标量数组表达式;@[length] 表示支持 json_length 表达式;@[contains|overlaps|structure_path] 表示支持对象数组的 json_overlaps 与 json_contains 表达式;@[extract|structure_hash] 或 @[extract|structure_value] 表示支持 json_extract 对象表达式,其中 structure_hash 在索引中存储对象的hash值,可以用于最小代价快速过滤,structure_value 在索引中存储对象值,可以用于精准过滤但存储成本偏高。可用于 json_overlaps、json_contains、json_extract、json_unquote、json_type、json_length、json_keys 与 json_depth 等。

创建JSON索引的本质是创建倒排索引,用法与全文索引一致。更多信息,请参见IMCI全文索引使用说明。

操作步骤

  1. 开启JSON索引功能:使用JSON索引前,需要先开启全局参数imci_enable_fts_json。

    参数名

    级别

    说明

    imci_enable_fts_json

    Global

    控制是否开启JSON索引功能。

    • ON(默认):开启。

    • OFF:关闭。

  2. 创建语法:

    CREATE TABLE table_name (
        column_name JSON COMMENT "imci_fts(type=4 mode=MODE json_paths={$.PATH1,$.PATH2,...})"
    ) COMMENT 'columnar=1';

    参数说明:

    • type=4:表示使用JSON分词器。

    • mode:指定JSON索引类型。0 与 1 为JSON数组索引(建议使用 1),2 为JSON键值索引,3 为JSON混合索引。

    • json_paths:指定需要索引的键或数组信息,在mode=2与mode=3时使用。例如,对于'{"k1":"v1","k2":2}',可以指定json_paths={$.k1}、json_paths={$.k2}或json_paths={$.k1,$.k2}。mode=3 时,还可以在每个 path 后面追加 @[...] 后缀声明该键需要加速的表达式,可选项为 extract、contains、overlaps、unquote、type、length、keys、depth、structure_path、structure_hash 与 structure_value,不指定时默认为 @[extract|contains|overlaps],例如 json_paths={$[*].k1@[extract|contains|overlaps|length] ,$[*].k2@[contains|overlaps]}。

JSON数组索引

JSON数组索引用于加速数组类型JSON列的查询,支持json_overlaps和json_contains表达式。

创建语法

ALTER TABLE table_name MODIFY COLUMN column_name JSON DEFAULT NULL COMMENT 'imci_fts(type=4 mode=1)';

加速json_overlaps查询

参数名

级别

说明

imci_convert_json_overlap_to_match

Global/Session

控制是否开启json_overlaps使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

开启后,json_overlaps表达式利用FtsTableScan加速。JSON分词器将目标值分解后分别在倒排索引中查询,最后求其并集(任意元素匹配即命中)。

mysql> EXPLAIN SELECT * FROM t1 WHERE json_overlaps(title, '[300, "301"]');
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                      |
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 1, max_query_mem = 1073741824)                                                   |
|  2 | └─Compute Scalar     |      |                                                                                                                 |
|  3 |   └─FtsTableScan     | t1   | Term: ("300(json_type(2))", "301(json_type(5))") Fallback: (JSON_OVERLAPS(t1.title, "[300, "301"](json)") <> 0) |
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------------+

加速json_contains查询

参数名

级别

说明

imci_convert_json_contains_to_match

Global/Session

控制是否开启json_contains使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

开启后,json_contains表达式利用FtsTableScan加速。JSON分词器将目标值分解后分别在倒排索引中查询,最后求其交集(所有元素都匹配才命中)。

mysql> EXPLAIN SELECT * FROM t1 WHERE json_contains(title, '[300, "301"]');
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                |
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 1, max_query_mem = 1073741824)                                             |
|  2 | └─Compute Scalar     |      |                                                                                                           |
|  3 |   └─FtsTableScan     | t1   | Term: ("300(json_type(2))", "301(json_type(5))") Fallback: (JSON_CONTAINS(t1.title, "[300, "301"]") <> 0) |
+----+----------------------+------+-----------------------------------------------------------------------------------------------------------+

JSON键值索引

JSON键值索引用于加速对象类型JSON列中特定键的等值查询,支持json_extract表达式。索引创建时通过json_paths指定需要索引的键,查询时根据键值对的值在倒排索引中快速定位匹配行。

创建语法

ALTER TABLE table_name MODIFY COLUMN column_name JSON DEFAULT NULL COMMENT 'imci_fts(type=4 mode=2 json_paths={$.k1,$.k2})';

加速json_extract查询

参数名

级别

说明

imci_convert_json_extract_to_match

Global/Session

控制是否开启json_extract使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

开启后,json_extract等值表达式利用FtsTableScan加速。以下示例查询$.k1值等于'1'的行:

mysql> EXPLAIN SELECT * FROM t1 WHERE json_extract(title, "$.k1") = '1';
+----+----------------------+------+------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                     |
+----+----------------------+------+------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 1, max_query_mem = 1073741824)                                  |
|  2 | └─Compute Scalar     |      |                                                                                                |
|  3 |   └─FtsTableScan     | t1   | Term: ("1(json_index(0),json_type(5))") Fallback: (JSON_EXTRACT(t1.title, "$.k1") = "1(json)") |
+----+----------------------+------+------------------------------------------------------------------------------------------------+

多个键值条件可以在同一查询中同时加速:

mysql> EXPLAIN SELECT * FROM t1 WHERE json_extract(title, "$.k1") = '1' AND json_extract(title, "$.k2") = 2;
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                                                                                                |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 1, max_query_mem = 1073741824)                                                                                                                             |
|  2 | └─Compute Scalar     |      |                                                                                                                                                                                           |
|  3 |   └─FtsTableScan     | t1   | Term: ("1(json_index(0),json_type(5))") Term: ("2(json_index(1),json_type(2))") Fallback: ((JSON_EXTRACT(t1.title, "$.k1") = "1(json)") AND (JSON_EXTRACT(t1.title, "$.k2") = "2(json)")) |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

JSON嵌套索引

JSON嵌套索引用于加速对象数组类型JSON列中特定键的数组查询,支持json_overlaps/json_contains与json_extract等嵌套查询。索引创建时通过json_paths指定对象数组中的索引键,查询时根据键值对的值在倒排索引中快速定位匹配行。

创建语法

ALTER TABLE table_name MODIFY COLUMN column_name JSON DEFAULT NULL COMMENT 'imci_fts(type=4 mode=2 json_paths={$[*].k1,$[*].k2})';

ALTER TABLE table_name MODIFY COLUMN column_name JSON DEFAULT NULL COMMENT 'imci_fts(type=4 mode=3 json_paths={$[*].k1@[extract|contains|overlaps|unquote|type|length|keys|depth|structure_path|structure_hash|structure_value] ,$[*].k2@[contains|overlaps]})';

加速JSON嵌套查询

json_overlaps、json_contains与json_extract等嵌套查询可以利用FtsTableScan加速。以[{"id": 1, "name": "张三"}, {"id": 2, "name": "李四"}, {"id": 3, "name": "陈一"}] 为例,可以通过json_paths={$[*].id, $[*].name}将JSON对象数组中对应键值解析出来添加到索引来加速查询。

mysql> EXPLAIN SELECT * FROM t1 WHERE json_overlaps(title->'$[*].id', '[1, 2]');
+----+----------------------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                                                                 |
+----+----------------------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 32, max_query_mem = 137438953472)                                                                                           |
|  2 | └─Compute Scalar     |      |                                                                                                                                                            |
|  3 |   └─FtsTableScan     | t1   | Term: (OR(1(json_index(0),json_type(2)), 2(json_index(0),json_type(2)))) Fallback: (JSON_OVERLAPS(JSON_EXTRACT(t1.title, "$[*].id"), "[1, 2](json)") <> 0) |
+----+----------------------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------+
mysql> EXPLAIN SELECT * FROM t1 WHERE json_contains(title->'$[*].name', '["张三", "陈一"]');
+----+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                                                                                            |
+----+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 32, max_query_mem = 137438953472)                                                                                                                      |
|  2 | └─Compute Scalar     |      |                                                                                                                                                                                       |
|  3 |   └─FtsTableScan     | t1   | Term: (AND(张三(json_index(1),json_type(5)), 陈一(json_index(1),json_type(5)))) Fallback: (JSON_CONTAINS(JSON_EXTRACT(t1.title, "$[*].name"), "["张三", "陈一"](json)") <> 0)            |
+----+----------------------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

JSON混合索引

JSON混合索引用于加速任意类型JSON列中特定键的标量、对象、标量数组与对象数组等查询,支持 json_overlaps、json_contains、json_extract、json_unquote、json_type、json_length、json_keys 与 json_depth 等表达式。索引创建时通过 json_paths 指定需要索引的键或数组,并在每个 path 后用 @[...] 后缀声明该键需要加速的表达式。

创建语法

ALTER TABLE table_name MODIFY COLUMN column_name JSON DEFAULT NULL COMMENT 'imci_fts(type=4 mode=3 json_paths={$[*].k1@[extract|contains|overlaps|unquote|type|length|keys|depth|structure_path|structure_hash|structure_value] ,$[*].k2@[contains|overlaps]})';

加速各类JSON查询

参数名

级别

说明

imci_convert_json_unquote_to_match

Global/Session

控制是否开启 json_unquote 使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

imci_convert_json_type_to_match

Global/Session

控制是否开启 json_type 使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

imci_convert_json_length_to_match

Global/Session

控制是否开启 json_length 使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

imci_convert_json_keys_to_match

Global/Session

控制是否开启 json_keys 使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

imci_convert_json_depth_to_match

Global/Session

控制是否开启 json_depth 使用JSON索引加速功能。

  • ON:开启。

  • OFF(默认):关闭。

imci_fts_json_structure_preference

Global/Session

控制在 @[structure_hash|structure_value] 均开启的情况下,查询优化选择对象的hash值还是对象值。

  • "HASH"(默认)

  • "VALUE"。

开启后,对应表达式利用 FtsTableScan 加速。以下示例查询 $.id 值等于 '21' 的行:

mysql> explain select id, title from t1 where json_unquote(title->'$.id') = '21';
+----+------------------------+------+----------------------------------------------------------------------------------------------------------------------------------+
| ID | Operator               | Name | Extra Info                                                                                                                       |
+----+------------------------+------+----------------------------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement       |      | IMCI Execution Plan (max_dop = 32, max_query_mem = unlimited)                                                                    |
|  2 | └─Compute Scalar       |      |                                                                                                                                  |
|  3 |   └─FILTER             |      | Cond: ((TRUE PRED) AND (JSON_UNQUOTE(JSON_EXTRACT(t1.title, "$.id")) = "21"))                                                    |
|  4 |     └─FtsTableScan     | t1   | Term: (AND("21"(json:index(0),type(STRING),src(UnquotedValue)))) Fallback: (JSON_UNQUOTE(JSON_EXTRACT(t1.title, "$.id")) = "21") |
+----+------------------------+------+----------------------------------------------------------------------------------------------------------------------------------+

以下示例查询JSON元素个数等于 1 的行:

mysql> explain select id, json_length(title), title from t1 where json_length(title) = 1;
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                  |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 32, max_query_mem = unlimited)                                               |
|  2 | └─Compute Scalar     |      |                                                                                                             |
|  3 |   └─FtsTableScan     | t1   | Term: (AND(1(json:index(0),type(UNSIGNED_INTEGER),src(LengthValue)))) Fallback: (JSON_LENGTH(t1.title) = 1) |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------+

当 @[structure_hash] 与 @[structure_value] 均已开启时,可以通过 imci_fts_json_structure_preference 指定使用对象值精准过滤:

mysql> set imci_fts_json_structure_preference = "VALUE";
mysql> explain select id, title from t1 where json_extract(title, '$.info') = cast('{"id": 10, "name": "name_10"}' as json);
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ID | Operator             | Name | Extra Info                                                                                                                                                                          |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|  1 | Select Statement     |      | IMCI Execution Plan (max_dop = 32, max_query_mem = unlimited)                                                                                                                       |
|  2 | └─Compute Scalar     |      |                                                                                                                                                                                     |
|  3 |   └─FtsTableScan     | t1   | Term: (AND(json_value({"id":10,"name":"name_10"})(json:index(0),type(OBJECT),src(JsonValue)))) Fallback: (JSON_EXTRACT(t1.title, "$.info") = "{"id": 10, "name": "name_10"}(json)") |
+----+----------------------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+