mysql5.7官网直译优化和索引--使用生成列的索引

来源:互联网 发布:网络直播你有什么看法 编辑:程序博客网 时间:2024/06/05 10:24
8.3.10 Optimizer Use of Generated Column Indexes 优化使用生成的列的索引
mysql支持索引被产生的列。例如:
CREATE TABLE t1 (f1 INT, gc INT AS (f1 + 1) STORED, INDEX (gc));
被产生的列gc,是表达式f1+1得到的。列被索引并且优化器能够使用该索引在执行计划的构造过程中。在下面的查询中,where条件引用了gc,所以优化器考虑是否有索引在该列上从而生成更有效的执行计划:
SELECT * FROM t1 WHERE gc > 9;
优化器能够使用在被生成的列上的索引来生成执行计划,即使没有按名称对这些列查询,也没有直接引用。在如下的查询中,并没有直接引用gc但是使用的表达式和gc定义匹配:
SELECT * FROM t1 WHERE f1 + 1 > 9;
优化器识别到表达式f1+1和gc的定义匹配并且gc是被索引的,所以它考虑使用索引来产生执行计划。你能看到使用EXPLAIN:
mysql> EXPLAIN SELECT * FROM t1 WHERE f1 + 1 > 9\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
   partitions: NULL
         type: range
possible_keys: gc
          key: gc
      key_len: 5
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using index condition
实际上,优化器通过被产生的列gc来取代了和其匹配的表达式f1+1。很明显得到重写了查询可以在扩展的EXPLAIN信息中查看,通过SHOW WARNINGS:
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`gc`
         AS `gc` from `test`.`t1` where (`test`.`t1`.`gc` > 9)
下面给出优化器要使用被产生的列上的索引的限制和条件:
1)对于一个查询表达式匹配一个被产生的列的定义,表达式必须恒等的且有相同的结果类型。例如,如果产生的列表达式是f1+1,优化器不能识别一个匹配如果查询是1+f1或者是f1+1(一个整数类型)不会匹配一个字符串。
2)优化器能够使用的操作是: =, <, <=, >, >=, BETWEEN, and IN().
   除BETWEEN和IN()之外的操作数,任何数都可以和被产生的列匹配。对于BETWEEN和IN().只有第一个参数能够被取代通过匹配被产生的列。并且其他参数必须有相同的结果类型。BETWEEN和IN()依然没有得到支持关于JSON值的对比。
3)被产生的列必须被定义为一个表达式,其中至少一个函数被调用,或者操作数被提名在之前的项目中。表达式不能由其他列的简单引用组成。例如,gc INT as (f1) SORTED 组成仅仅是一个列的引用,所以索引在gc列上不会被考虑。
4)对于比较字符串类型的被产生的列,其中比较的值来自JSON函数,返回一个被引用的字符串,JSON_UNQUOTE()被需要再列的定义去移除各位的引用从函数值中。(对于直接比较一个字符串和函数结果,JSON比较处理去掉引用,但是这不会引起索引查询)例如,写一个列定义如下:
doc_name TEXT AS (JSON_EXTRACT(jdoc, '$.name')) STORED
写它像这样:
doc_name TEXT AS (JSON_UNQUOTE(JSON_EXTRACT(jdoc, '$.name'))) STORED
通过后者的定义,优化器能够查明对于如下两种比较:
... WHERE JSON_EXTRACT(jdoc, '$.name') = 'some_string' ...
... WHERE JSON_UNQUOTE(JSON_EXTRACT(jdoc, '$.name')) = 'some_string' ...
没有JSON_UNQUOTE()在列定义中,优化器查明的匹配只有第一个这种的表达式。
5)如果优化器没有选择希望的索引,一个索引提示能够强制优化器使用从而给出一个不同的选择。
到此关于索引和优化的介绍就结束了。
阅读全文
0 0
原创粉丝点击