MySQL8.0 Generated Column 函数索引(四 ) —— JSON列的Generated Column 索引

在Innodbr中JSON 列使用函数索引

JSON类型的列不能直接创建索引,但可以间接创建索引,可以定义一个 Generated Column列,该列提取JSON字段的部分信息,然后在Generated Column列上创建索引,如以下示例所示:

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的输出所示:

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)

此技术还可用于提供间接引用其他类型(例如几何列)的列的索引。

在NDB Cluster中JSON 列使用函数索引

还可以在MySQL NDB集群中使用JSON列的间接索引,条件如下:

  • NDB在内部将JSON列作为BLOB处理。这意味着,任何具有一个或多个JSON列的NDB表都必须有主键,否则无法将其记录在二进制日志中。
  • NDB存储引擎不支持对 Generated Column列的索引。由于生成列的默认值为VIRTUAL,因此必须显式指定generated column 列的类型为STORED ,然后再创建索引。

这里用于创建表jempn的CREATE TABLE语句是前面创建jemp表的一个版本,通过修改使其与NDB引擎兼容:

CREATE TABLE jempn ( a BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, c JSON DEFAULT NULL, g INT GENERATED ALWAYS AS (c->"$.name") STORED, INDEX i (g) ) ENGINE=NDB;

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

INSERT INTO jempn (a, c) VALUES (NULL, '{"id": "1", "name": "Fred"}'), (NULL, '{"id": "2", "name": "Wilma"}'), (NULL, '{"id": "3", "name": "Barney"}'), (NULL, '{"id": "4", "name": "Betty"}');

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

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 type: range possible_keys: i key: i key_len: 5 ref: NULL rows: 3 filtered: 100.00 Extra: Using where with pushed condition (`test`.`jempn`.`g` > 2) 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`.`jempn`.`c`,'$.name')) AS `name` from `test`.`jempn` where (`test`.`jempn`.`g` > 2) 1 row in set (0.00 sec)

Stored 类型的Generated Column列 使用DataMemory,此类型列上的索引使用IndexMemory。

 

 

https://dev.mysql.com/doc/refman/8.0/en/create-table-secondary-indexes.html#json-column-indirect-index

MySQL generated columns are virtual columns that are not stored physically on the disk but are computed based on an expression or formula. They are also known as computed columns or virtual columns. Generated columns were introduced in MySQL version 5.7 and they provide a way to create a column whose values are computed from an expression. The expression can involve one or more other columns in the same table, constants, or functions. To create a generated column, you need to specify the column name, data type, and the expression that computes the values for that column. Here is an example: ``` CREATE TABLE employees ( id INT PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), salary INT, tax_rate DECIMAL(4,2), net_salary DECIMAL(10,2) GENERATED ALWAYS AS (salary - (salary * tax_rate)) STORED ); ``` In this example, the `net_salary` column is a generated column whose value is computed from the `salary` and `tax_rate` columns using the expression `(salary - (salary * tax_rate))`. Generated columns can be either `STORED` or `VIRTUAL`. A `STORED` generated column is computed when a row is inserted or updated and its value is stored on the disk like any other column. A `VIRTUAL` generated column is computed dynamically when it is accessed and its value is not stored on the disk. Generated columns can provide significant performance benefits in certain scenarios because they can avoid the need to compute values in application code or in queries. However, they can also increase the storage requirements for a table, so it's important to use them judiciously.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

October-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值