MySQL通过通用列索引来提供一个JSON列索引

通过通用列索引来提供一个JSON列索引,不能直接对JSON列进行索引。要创建间接引用此类列的索引,可以定义一个生成的列,提取应该索引的信息,然后在生成的列上创建索引,如本例所示

mysql> CREATE TABLE jemp (
    -> c JSON,
    -> g INT GENERATED ALWAYS AS (c->"$.id"),
    -> INDEX i (g)
    -> );
Query OK, 0 rows affected (0.12 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(`mysql`.`jemp`.`c`,'$.name')) AS `name` from `mysql`.`jemp` where (`mysql`.`jemp`.`g` > 2)
1 row in set (0.00 sec)

我们已经包装了本例中最后一条语句的输出,以适应查看区域。

在MySQL 5.7.9及以后的版本中支持->操作符。从MySQL 5.7.13开始支持->>操作符

当对一个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(`mysql`.`jemp`.`c`,'$.name')) AS `c->>"$.name"` from `mysql`.`jemp` where (`mysql`.`jemp`.`g` > 2) order by json_extract(`mysql`.`jemp`.`c`,'$.name')
1 row in set (0.00 sec)

可以看到->和->>操作符使用json_extract()和json_unquote()函数来描述。这种技术可以被用来为那些不能被直接索引的间接引用列提供索引 ,比如geometry列。

发表评论

电子邮件地址不会被公开。