首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL 之 JSON 支持(二)—— JSON 索引

MySQL 之 JSON 支持(二)—— JSON 索引

作者头像
用户1148526
发布于 2024-06-07 08:27:31
发布于 2024-06-07 08:27:31
1.2K00
代码可运行
举报
文章被收录于专栏:Hadoop数据仓库Hadoop数据仓库
运行总次数:0
代码可运行

官方文档链接:

一、多值索引

MySQL 8.0.17 开始,InnoDB 支持多值索引。多值索引是在存储数组值的列上定义的辅助索引。“一般”索引对于每个数据记录有一个索引记录(1:1)。多值索引中单个数据记录可以具有多个索引记录(N:1)。多值索引用于对 JSON 数组进行索引。例如,在下面的 JSON 文档中,对邮政编码数组定义的多值索引为每个邮政编码创建一个索引记录,每个索引记录引用相同的数据记录。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    "user":"Bob",
    "user_id":31,
    "zipcode":[94477,94536]
}

1. 创建多值索引

可以在 CREATE TABLE、ALTER TABLE 或 CREATE INDEX 语句中创建多值索引。这需要在索引定义中使用 CAST(... AS ... ARRAY),它将 JSON 数组中相同类型的标量值强制转换为 SQL 数据类型的数组。然后使用 SQL 数据类型数组中的值透明地生成虚拟列;最后,在虚拟列上创建一个函数索引(也称为虚拟索引)。在 SQL 数据类型数组中的值的虚拟列上定义的函数索引,构成多值索引。

以下列表中的示例显示了在名为 customers 表的 custinfo JSON 列的 $.zipcode 数组上创建多值索引 zips 的三种不同方式。在每种情况下,JSON 数组都被强制转换为包含 UNSIGNED 整数值的 SQL 数据类型数组。

只建表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE customers (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    custinfo JSON,
    INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) )
    );

建表后修改表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE customers (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    custinfo JSON
    );

ALTER TABLE customers ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );

建表后建索引

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE customers (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    custinfo JSON
    );

CREATE INDEX zips ON customers ( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );

多值索引也可以定义为复合索引的一部分。下面的示例显示了一个复合索引,它包括两个单值部分(对 id 和 modified 列)和一个多值部分(对 custinfo 列):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE customers (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    custinfo JSON
    );

ALTER TABLE customers ADD INDEX comp(id, modified,
    (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );

一个复合索引中只能使用一个多值键部分。多值键部分可以相对于索引的其它部分以任何顺序使用。换句话说,刚才显示的 ALTER TABLE 语句可能使用 comp(id, (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY), modified)) 或任何其它排序,而且仍然有效。

2. 使用多值索引

在 WHERE 子句中指定以下函数时,优化器使用多值索引来获取记录:

  • MEMBER OF()
  • JSON_CONTAINS()
  • JSON_OVERLAPS()

可以通过使用以下 CREATE TABLE 和 INSERT 语句创建 customers 表并添加数据来演示这一点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> CREATE TABLE customers (
    ->     id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ->     modified DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    ->     custinfo JSON
    ->     );
Query OK, 0 rows affected (0.51 sec)

mysql> INSERT INTO customers VALUES
    ->     (NULL, NOW(), '{"user":"Jack","user_id":37,"zipcode":[94582,94536]}'),
    ->     (NULL, NOW(), '{"user":"Jill","user_id":22,"zipcode":[94568,94507,94582]}'),
    ->     (NULL, NOW(), '{"user":"Bob","user_id":31,"zipcode":[94477,94507]}'),
    ->     (NULL, NOW(), '{"user":"Mary","user_id":72,"zipcode":[94536]}'),
    ->     (NULL, NOW(), '{"user":"Ted","user_id":56,"zipcode":[94507,94582]}');
Query OK, 5 rows affected (0.07 sec)
Records: 5  Duplicates: 0  Warnings: 0

首先对 customers 表执行三个查询,每个查询分别使用 MEMBER OF()、JSON_CONTAINS() 和 JSON_OVERLAPS(),每个查询的结果如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SELECT * FROM customers
    ->     WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+---------------------+-------------------------------------------------------------------+
| id | modified            | custinfo                                                          |
+----+---------------------+-------------------------------------------------------------------+
|  2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} |
|  3 | 2019-06-29 22:23:12 | {"user": "Bob", "user_id": 31, "zipcode": [94477, 94507]}         |
|  5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]}         |
+----+---------------------+-------------------------------------------------------------------+
3 rows in set (0.00 sec)

mysql> SELECT * FROM customers
    ->     WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+---------------------+-------------------------------------------------------------------+
| id | modified            | custinfo                                                          |
+----+---------------------+-------------------------------------------------------------------+
|  2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} |
|  5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]}         |
+----+---------------------+-------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM customers
    ->     WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+---------------------+-------------------------------------------------------------------+
| id | modified            | custinfo                                                          |
+----+---------------------+-------------------------------------------------------------------+
|  1 | 2019-06-29 22:23:12 | {"user": "Jack", "user_id": 37, "zipcode": [94582, 94536]}        |
|  2 | 2019-06-29 22:23:12 | {"user": "Jill", "user_id": 22, "zipcode": [94568, 94507, 94582]} |
|  3 | 2019-06-29 22:23:12 | {"user": "Bob", "user_id": 31, "zipcode": [94477, 94507]}         |
|  5 | 2019-06-29 22:23:12 | {"user": "Ted", "user_id": 56, "zipcode": [94507, 94582]}         |
+----+---------------------+-------------------------------------------------------------------+
4 rows in set (0.00 sec)

下面对这三个查询中的每一个运行 EXPLAIN:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    5 |   100.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

刚才显示的三个查询都不能使用任何键。为了解决这个问题,可以在 JSON 列(custinfo)的 zipcode 数组上添加一个多值索引,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> ALTER TABLE customers
    ->     ADD INDEX zips( (CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)) );
Query OK, 0 rows affected (0.47 sec)
Records: 0  Duplicates: 0  Warnings: 0

再来运行前面的 EXPLAIN 语句时,能看到查询可以(并且确实)使用刚创建的索引 zips:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE 94507 MEMBER OF(custinfo->'$.zipcode');
+----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | ref  | zips          | zips | 9       | const |    1 |   100.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE JSON_CONTAINS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | range | zips          | zips | 9       | NULL |    6 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> EXPLAIN SELECT * FROM customers
    ->     WHERE JSON_OVERLAPS(custinfo->'$.zipcode', CAST('[94507,94582]' AS JSON));
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table     | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | customers | NULL       | range | zips          | zips | 9       | NULL |    6 |   100.00 | Using where |
+----+-------------+-----------+------------+-------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

多值索引可以定义为唯一键。如果定义为唯一键,当插入多值索引中已存在的值时会返回重复键错误。如果已经存在重复的值,则添加唯一的多值索引时会失败,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> ALTER TABLE customers DROP INDEX zips;
Query OK, 0 rows affected (0.55 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> ALTER TABLE customers
    ->     ADD UNIQUE INDEX zips((CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)));
ERROR 1062 (23000): Duplicate entry '[94507, ' for key 'customers.zips'
mysql> ALTER TABLE customers
    ->     ADD INDEX zips((CAST(custinfo->'$.zipcode' AS UNSIGNED ARRAY)));
Query OK, 0 rows affected (0.36 sec)
Records: 0  Duplicates: 0  Warnings: 0

3. 多值索引的特性

多值索引具有以下附加特性:

  • 影响多值索引的 DML 操作的处理方式与影响普通索引的 DML 操作相同,唯一的区别是单个聚集索引记录可能有多个插入或更新。
  • 多值索引的可空性:
    • 如果多值键部分具有空数组,则不会向索引中添加任何条目,并且无法通过索引扫描访问对应的数据记录。
    • 如果多值键部分生成返回 NULL 值,则会将包含 NULL 的单个条目添加到多值索引中。如果键部分定义为 NOT NULL,则会报告错误。
    • 如果类型数组列设置为 NULL,则存储引擎将存储一条包含指向数据记录的 NULL 的记录。
    • 在被索引数组中不允许 JSON null 值。如果任何返回值为 NULL,则将其视为 JSON null,并报告 Invalid JSON value 错误。
  • 因为多值索引是虚拟列上的虚拟索引,所以它们必须遵守与虚拟生成列上的辅助索引相同的规则。
  • 不会为空数组添加索引记录。

4. 多值索引的限制

多值索引有以下限制:

每个多值索引只允许有一个多值键部分。但是,CAST(... AS ... ARRAY) 表达式可以引用 JSON 文档中的多个数组,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CAST(data->'$.arr[*][*]' AS UNSIGNED ARRAY)

在这种情况下,所有与 JSON 表达式匹配的值都作为单个扁平化数组存储在索引中。

具有多值键部分的索引不支持排序,因此不能用作主键。出于同样的原因,不能使用 ASC 或 DESC 关键字定义多值索引。

多值索引不能是覆盖索引。

多值索引的每条记录的最大值数由单个 undo log 页上可存储的数据量决定,该数据量为 65221 字节(64K 减去 315 字节的开销),这意味着键值的最大总长度也是 65221 字节。键的最大数量取决于各种因素,这会妨碍定义特定的限制。例如,测试表明,多值索引允许每条记录有多达 1604 个整数键。当达到限制时,会报告类似于以下的错误:错误3905(HY000):ERROR 3905 (HY000): Exceeded max number of values per record for multi-valued index 'idx' by 1 value(s)。

多值键部分中唯一允许的表达式类型是 JSON 表达式。表达式不需要引用插入索引列的 JSON 文档中的现有元素,但其本身必须在语法上有效。

由于同一聚集索引中的索引记录分散在多值索引中,因此多值索引不支持范围扫描或仅索引扫描。

外键声明中不允许使用多值索引。

不能为多值索引定义索引前缀。

不能在转换为 BINARY 的数据上定义多值索引(参阅 CAST() 函数的描述)。

不支持在线创建多值索引,这意味着该操作使用了 ALGORITHM=COPY。参阅性能和空间要求

多值索引不支持以下两种字符集和排序规则组合以外的字符集和排列规则:

  • 具有默认二进制排序规则的二进制字符集。
  • 使用默认 utf8mb4_0900_as_cs 排序规则的 utf8mb4 字符集。

与 InnoDB 表列上的其它索引一样,不能使用 USING HASH 创建多值索引;这样做会导致警告:This storage engine does not support the HASH index algorithm, storage engine default was used instead. (USING BTREE is supported as usual.)

二、辅助索引与生成列

InnoDB 的虚拟生成列上支持辅助索引,不支持其它索引类型。在虚拟列上定义的辅助索引有时被称为“虚拟索引”。

可以在一个或多个虚拟列上,或者在虚拟列和普通列的组合上,或者在存储的生成列上创建辅助索引。包括虚拟列的辅助索引可以定义为 UNIQUE。

在虚拟生成列上创建辅助索引时,生成的列值会物化到索引的记录中。如果索引是覆盖索引(包括查询检索的所有列),则生成的列值将从索引结构中的物化值中检索,而不是“动态”计算。

在对虚拟列使用辅助索引时,由于 INSERT 和 UPDATE 操作期间在辅助索引记录中物化虚拟列值时执行的计算,需要考虑额外的写入成本。即使有额外的写入成本,虚拟列上的辅助索引也可能比存储的生成列更可取,后者在聚集索引中被物化,从而导致大表需要更多磁盘空间和内存。如果没有在虚拟列上定义辅助索引,则会产生额外的读取成本,因为每次检查列的行时都必须计算虚拟列值。

被索引的虚拟列值会记录 MVCC,以避免在回滚或清除操作期间对生成列的值进行不必要的重新计算。记录值的数据长度受索引键限制,COMPACT 和 REDUNDANT 行格式为 767 字节,DYNAMIC 和 COMPRESED 行格式为 3072 字节。

在虚拟列上添加或删除辅助索引是一种就地操作。

1. 为生成列创建索引以提供 JSON 列索引

正如在文档其它地方所指出的,JSON 列不能直接索引。为了间接创建引用这些列的索引,可以定义一个生成列来提取要索引的信息,然后在生成列上创建索引,如本例所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> CREATE TABLE jemp (
    ->     c JSON,
    ->     g INT GENERATED ALWAYS AS (c->"$.id"),
    ->     INDEX i (g)
    -> );
Query OK, 0 rows affected (0.28 sec)

mysql> INSERT INTO jemp (c) VALUES
     >   ('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'),
     >   ('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}');
Query OK, 4 rows affected (0.04 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT c->>"$.name" AS name
     >     FROM jemp WHERE g > 2;
+--------+
| name   |
+--------+
| Barney |
| Betty  |
+--------+
2 rows in set (0.00 sec)

mysql> EXPLAIN SELECT c->>"$.name" AS name
     >    FROM jemp WHERE g > 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: jemp
   partitions: NULL
         type: range
possible_keys: i
          key: i
      key_len: 5
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name'))
AS `name` from `test`.`jemp` where (`test`.`jemp`.`g` > 2)
1 row in set (0.00 sec)

(已将本例中最后一条语句的输出进行了折行以适应显示区。) 在 SELECT 或其它 SQL 语句中使用 EXPLAIN 时,如果该语句包含一个或多个使用 -> 或 ->> 运算符的表达式,则会使用 JSON_EXTRACT() 和(如果需要)JSON_UNQUOTE() 将这些表达式转换为等效表达式,如下面 EXPLAIN 语句后的 SHOW WARNINGS 的输出所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN SELECT c->>"$.name"
     > FROM jemp WHERE g > 2 ORDER BY c->"$.name"\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: jemp
   partitions: NULL
         type: range
possible_keys: i
          key: i
      key_len: 5
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: Using where; Using filesort
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name')) AS
`c->>"$.name"` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) order by
json_extract(`test`.`jemp`.`c`,'$.name')
1 row in set (0.00 sec)

有关更多信息和示例,请参阅 -> 和 ->> 运算符的描述,以及 JSON_EXTRACT() 和 JSON_UNQUOTE() 函数的描述。

此技术还可用于提供间接引用无法直接索引的其它类型的列的索引,例如 GEOMETRY 列。

在 MySQL 8.0.21 及更高版本中,还可以使用带有表达式的 JSON_VALUE() 函数在 JSON 列上创建索引,可用于优化使用该表达式查询。有关更多信息和示例,请参阅该函数的描述。

2. NDB 集群中的 JSON 列和间接索引

也可以在 MySQL NDB 集群中使用 JSON 列的间接索引,但需满足以下条件:

  1. NDB 将 JSON 列值作为 BLOB 在内部进行处理。这意味着,任何具有一个或多个 JSON 列的 NDB 表都必须有主键,否则它将无法记录在二进制日志中。
  2. NDB 存储引擎不支持对虚拟列进行索引。由于生成列的默认值是 VIRTUAL,因此必须显式指定间接索引将要应用的生成列为 STORED。

用于创建此处显示的表 jempn 的 CREATE TABLE 语句是前面显示的 jemp 表的另一个版本,经过修改使其与NDB兼容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE jempn (
  a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  c JSON DEFAULT NULL,
  g INT GENERATED ALWAYS AS (c->"$.id") STORED,
  INDEX i (g)
) ENGINE=NDB;

可以使用以下 INSERT 语句填充此表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
INSERT INTO jempn (c) VALUES
  ('{"id": "1", "name": "Fred"}'),
  ('{"id": "2", "name": "Wilma"}'),
  ('{"id": "3", "name": "Barney"}'),
  ('{"id": "4", "name": "Betty"}');

现在 NDB 可以使用索引 i,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> EXPLAIN SELECT c->>"$.name" AS name
    ->           FROM jempn WHERE g > 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: jempn
   partitions: p0,p1,p2,p3
         type: range
possible_keys: i
          key: i
      key_len: 5
          ref: NULL
         rows: 3
     filtered: 100.00
        Extra: Using pushed condition (`test`.`jempn`.`g` > 2)
1 row in set, 1 warning (0.01 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select
json_unquote(json_extract(`test`.`jempn`.`c`,'$.name')) AS `name` from
`test`.`jempn` where (`test`.`jempn`.`g` > 2)   
1 row in set (0.00 sec)

应该记住,存储的生成列,以及这些列上的任何索引都使用 DataMemory。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL 8.0 新特性:多值索引 --如何给JSON数组添加索引(三)
上一篇文章《MySQL如何给JSON列添加索引(二)》中,我们介绍了如何给JSON列添加索引,那么接下来,我们看下如何给JSON数组添加索引?
SEian.G
2021/07/07
15.6K1
MySQL 8.0中的JSON增强
现在很多应用环境中都能看到JSON灵活的影子。各阶段数据层次的递归层次,能很好的分辨。一直对MySQL的JSON很期待的,最近才有时间研究一下。
数据和云
2021/07/09
4.3K0
MySQL如何给JSON列添加索引(二)
上一篇文章《MySQL 8.0 JSON增强到底有多强?(一)》,我们简单介绍了MySQL中JSON数据类型,相信大家对JSON数据类型有了一定的了解,那么今天我们来简单看下如何在JSON列上添加索引?
SEian.G
2021/07/07
8.1K0
分布式关系型数据库-TDSQL for Mysql
用于产品业务相关数据存储,兼容mysql,支持弹性自动水平扩容(实际上是因为接手的时候,已经用了这种数据库)TDSQL for MySQL。
二木
2022/05/25
2.7K0
分布式关系型数据库-TDSQL for Mysql
MySQL高效索引之覆盖索引
如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作
星哥玩云
2022/08/17
9930
MySQL 索引管理与执行计划
1.1 索引的介绍   索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信
惨绿少年
2017/12/27
2K0
MySQL 索引管理与执行计划
mysql explain用法和结果的含义
转自:http://blog.chinaunix.net/uid-540802-id-3419311.html
袁新栋-jeff.yuan
2020/08/26
1.7K0
MySQL8索引篇:性能提升了100%!!
今天我们一起来聊聊MySQL 8.x版本中新增的三大索引。MySQL 8.x中新增了三种索引方式,这三种索引方式直接让MySQL原地起飞了,如下所示。
冰河
2022/06/15
3K0
3.联合索引、覆盖索引及最左匹配原则|MySQL索引学习
在数据检索的过程中,经常会有多个列的匹配需求,今天介绍下联合索引的使用以及最左匹配原则的案例。
GreatSQL社区
2022/04/18
1.7K0
MySQL 的 JSON 数据类型,YYDS!
用过 MySQL 都知道,关系型的结构化存储存在一定的弊端,因为它需要预先定义好所有的列以及列对应的类型。但是业务在发展过程中,或许需要扩展单个列的描述功能,这时,如果能用好 JSON 数据类型,那就能打通关系型和非关系型数据的存储之间的界限,为业务提供更好的架构选择。
JavaFish
2022/03/15
2.5K0
MySQL EXPLAIN SQL 输出信息描述
EXPLAIN语句能够被用于获取一些关于SQL执行时的相关信息,比如表的连接顺序,对表的方式方式等等。通过对该相关信息进行进一步的分析,我们 可以通过对表添加适当的索引,以及优化连接顺序,使用提示等等手段来达到使SQL高效运行的目的。本文描述了EXPLAIN的用法并给出了相关示例。 一、EXPLAIN概述 EXPLAIN 语句主要是用于解析SQL执行计划,通过分析执行计划采取适当的优化方式提高SQL运行的效率。 EXPLAIN 语句输出通常包括id列,select_type,table,ty
Leshami
2018/08/13
1.2K0
MySQL8.0 优化器介绍(三)
为了让读者对join优化 有更深的了解,章节里的sql例子,留了一些思考和动手的问题。可能大家得到的答案会不同,但探索未知的过程,方式应该是一样的。
GreatSQL社区
2023/08/10
4640
MySQL8.0 优化器介绍(三)
MySQL - Explain深度剖析
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
小小工匠
2021/08/17
5100
MySQL 5.7原生JSON格式支持
在MySQL与PostgreSQL的对比中,PG的JSON格式支持优势总是不断被拿来比较。其实早先MariaDB也有对非结构化的数据进行存 储的方案,称为dynamic column,但是方案是通过BLOB类型的方式来存储。这样导致的问题是查询性能不高,不能有效建立索引,与一些文档数据库对比,优势并不大,故在社区 的反应其实比较一般。当然,MariaDB的dynamic column功能还不仅限于非结构化数据的存储,但不在本文进行展开。 MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生
小小科
2018/05/02
4K0
第21期:索引设计(函数索引)
通常来讲,索引都是基于字段本身或者字段前缀(第 20 篇),而函数索引是基于字段本身加上函数、操作符、表达式等计算而来。如果将表达式或者操作符也看做函数的话,简单来说,这样的索引就可以统称函数索引。
爱可生开源社区
2021/02/26
8570
第21期:索引设计(函数索引)
一文搞懂MySQL索引(清晰明了)[通俗易懂]
索引是对数据库表中一列或多列的值进行排序的一种结构。MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。
全栈程序员站长
2022/09/12
1.4K0
一文搞懂MySQL索引(清晰明了)[通俗易懂]
MySQL - 践行索引优化
key_len : 显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
小小工匠
2021/08/17
5730
MySQL 允许你在 JSON 数据上创建索引
在student表的courses字段中,为JSON数据内的course_id键创建索引。
贺春旸的技术博客
2024/09/03
4470
MySQL 允许你在 JSON 数据上创建索引
Mysql索引原理及应用场景
在工作当中,涉及到Mysql的查询,我们经常会遇到给某个表某个字段加索引的诉求,加上索引能够让我们的sql得到查询速度上的提升。但索引的原理是什么呢,他又是怎么工作的,需要开发者对基础知识有一定的了解。
benym
2022/08/30
1.4K0
Mysql索引原理及应用场景
分析MySQL中隐式转换导致查询结果错误及索引不可用
通过上述的测试结果可以发现,针对数据类型字段,即使类型不一致,并不影响是否使用索引,执行计划是一样的,不会产生隐式转换。但仍然建议在开发程序和生产库中尽量避免出现这样的SQL。
SEian.G
2021/03/03
2K0
相关推荐
MySQL 8.0 新特性:多值索引 --如何给JSON数组添加索引(三)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档