函数索引顾名思义就是加给字段加了函数的索引,这里的函数也可以是表达式。所以也叫表达式索引。

MySQL 5.7 推出了虚拟列的功能,MySQL8.0的函数索引内部其实也是依据虚拟列来实现的。

我们考虑以下几种场景:

1.对比日期部分的过滤条件。

SELECT ...FROM tb1WHERE date(time_field1) = current_date;

2.两字段做计算。

SELECT ...FROM tb1WHERE field2 + field3 = 5;

3.求某个字段中间某子串。

SELECT ...FROM tb1WHERE substr(field4, 5, 9) = 'actionsky';

4.求某个字段末尾某子串。

SELECT ...FROM tb1WHERE RIGHT(field4, 9) = 'actionsky';

5.求JSON格式的VALUE。

SELECT ...FROM tb1WHERE CAST(field4 ->> '$.name' AS CHAR(30)) = 'actionsky';

以上五个场景如果不用函数索引,改写起来难易不同。不过都要做相关修改,不是过滤条件修正就是表结构变更添加冗余字段加额外索引。

比如第1个场景改写为,

SELECT ...FROM tb1WHERE time_field1 >= concat(current_date, ' 00:00:00')    AND time_field1 <= concat(current_date, '23:59:59');

再比如第4个场景的改写,

由于是求最末尾的子串,只能添加一个新的冗余字段,并且做相关的计划任务来一定频率的异步更新或者添加触发器来实时更新此字段值。

SELECT ...FROM tb1WHERE field4_suffix = 'actionsky';

那我们看到,改写也可以实现,不过这样的SQL就没有标准化而言,后期不能平滑的迁移了。

MySQL 8.0 推出来了函数索引让这些变得相对容易许多。

不过函数索引也有自己的缺陷,就是写法很固定,必须要严格按照定义的函数来写,不然优化器不知所措。

我们来把上面那些场景实例化

示例表结构,

总记录数

mysql> SELECT COUNT(*)FROM t_func;+----------+| count(*) |+----------+|    16384 |+----------+1 row in set (0.01 sec)

我们把上面几个场景的索引全加上。

mysql > ALTER TABLE t_func ADD INDEX idx_log_time ( ( date( log_time ) ) ),ADD INDEX idx_u1 ( ( rank1 + rank2 ) ),ADD INDEX idx_suffix_str3 ( ( RIGHT ( str3, 9 ) ) ),ADD INDEX idx_substr_str1 ( ( substr( str1, 5, 9 ) ) ),ADD INDEX idx_str2 ( ( CAST( str2 ->> '$.name' AS CHAR ( 9 ) ) ) );QUERY OK,0 rows affected ( 1.13 sec ) Records : 0 Duplicates : 0 WARNINGS : 0

我们再看下表结构, 发现好几个已经被转换为系统自己的写法了。

MySQL 8.0 还有一个特性,就是可以把系统隐藏的列显示出来。

我们用show extened 列出函数索引创建的虚拟列,

上面5个随机字符串列名为函数索引隐式创建的虚拟COLUMNS。

我们先来看看场景2,两个整形字段的相加,

mysql> SELECT COUNT(*)FROM t_funcWHERE rank1 + rank2 = 121;+----------+| count(*) |+----------+|      878 |+----------+1 row in set (0.00 sec)

看下执行计划,用到了idx_u1函数索引,

mysql> explain SELECT COUNT(*)FROM t_funcWHERE rank1 + rank2 = 121G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t_func   partitions: NULL         type: refpossible_keys: idx_u1          key: idx_u1      key_len: 9          ref: const         rows: 878     filtered: 100.00        Extra: NULL1 row in set, 1 warning (0.00 sec)

那如果我们稍微改下这个SQL的执行计划,发现此时不能用到函数索引,变为全表扫描了,所以要严格按照函数索引的定义来写SQL。

mysql> explain SELECT COUNT(*)FROM t_funcWHERE rank1 = 121 - rank2G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t_func   partitions: NULL         type: ALLpossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: 16089     filtered: 10.00        Extra: Using where1 row in set, 1 warning (0.00 sec)

再来看看场景1的的改写和不改写的性能简单对比,

mysql> SELECT *FROM t_funcWHERE date(log_time) = '2019-04-18'LIMIT 1G*************************** 1. row ***************************      id: 2   rank1: 1    str1: test-actionsky-test    str2: {"age": 30, "name": "dell"}   rank2: 120    str3: test-actionskylog_time: 2019-04-18 10:04:531 row in set (0.01 sec)

我们把普通的索引加上。

mysql > ALTER TABLE t_func ADD INDEX idx_log_time_normal ( log_time );QUERY OK,0 rows affected ( 0.36 sec ) Records : 0 Duplicates : 0 WARNINGS : 0

然后改写下SQL看下。

mysql> SELECT *FROM t_funcWHERE date(log_time) >= '2019-04-18 00:00:00'    AND log_time < '2019-04-19 00:00:00'*************************** 1. row ***************************      id: 2   rank1: 1    str1: test-actionsky-test    str2: {"age": 30, "name": "dell"}   rank2: 120    str3: test-actionskylog_time: 2019-04-18 10:04:531 row in set (0.01 sec)

两个看起来没啥差别,我们仔细看下两个的执行计划:

  • 普通索引
mysql> explain format=json SELECT *FROM t_funcWHERE log_time >= '2019-04-18 00:00:00'    AND log_time < '2019-04-19 00:00:00'LIMIT 1G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "630.71"    },    "table": {      "table_name": "t_func",      "access_type": "range",      "possible_keys": [        "idx_log_time_normal"      ],      "key": "idx_log_time_normal",      "used_key_parts": [        "log_time"      ],      "key_length": "6",      "rows_examined_per_scan": 1401,      "rows_produced_per_join": 1401,      "filtered": "100.00",      "index_condition": "((`ytt`.`t_func`.`log_time` >= '2019-04-18 00:00:00') and (`ytt`.`t_func`.`log_time` < '2019-04-19 00:00:00'))",      "cost_info": {        "read_cost": "490.61",        "eval_cost": "140.10",        "prefix_cost": "630.71",        "data_read_per_join": "437K"      },      "used_columns": [        "id",        "rank1",        "str1",        "str2",        "rank2",        "str3",        "log_time",        "cast(`log_time` as date)",        "(`rank1` + `rank2`)",        "right(`str3`,9)",        "substr(`str1`,5,9)",        "cast(json_unquote(json_extract(`str2`,_utf8mb4'$.name')) as char(9) charset utf8mb4)"      ]    }  }}1 row in set, 1 warning (0.00 sec)
  • 函数索引
mysql> explain format=json SELECT COUNT(*)FROM t_funcWHERE date(log_time) = '2019-04-18'LIMIT 1G*************************** 1. row ***************************EXPLAIN: {  "query_block": {    "select_id": 1,    "cost_info": {      "query_cost": "308.85"    },    "table": {      "table_name": "t_func",      "access_type": "ref",      "possible_keys": [        "idx_log_time"      ],      "key": "idx_log_time",      "used_key_parts": [        "cast(`log_time` as date)"      ],      "key_length": "4",      "ref": [        "const"      ],      "rows_examined_per_scan": 1401,      "rows_produced_per_join": 1401,      "filtered": "100.00",      "cost_info": {        "read_cost": "168.75",        "eval_cost": "140.10",        "prefix_cost": "308.85",        "data_read_per_join": "437K"      },      "used_columns": [        "log_time",        "cast(`log_time` as date)"      ]    }  }}1 row in set, 1 warning (0.00 sec)mysql>

从上面的执行计划看起来区别不是很大, 唯一不同的是,普通索引在CPU的计算上消耗稍微大点,见红色字体。

当然,有兴趣的可以大并发的测试下,我这仅仅作为功能性进行一番演示。

tp5更新某字段加1_爱可生详解MySQL 8.0:索引特性1-函数索引相关推荐

  1. java创建mysql sche_爱可生详解MySQL|入门必看DBLE中间件使用指南第一章:初识DBLE...

    目录: 一.DBLE项目资料 二.环境准备 安装JDK环境 三.安装DBLE 四.配置DBLE 应用场景一:数据拆分 应用场景二:读写分离 五.总结 DBLE 项目资料 DBLE 是企业级开源分布式中 ...

  2. mysql dbversion_爱可生详解MySQL|不能从MySQL 8.0 复制到 5.8?一招教你解决

    作者:Vinicius Grippa 管长龙 译 本文中,我们将讨论如何设置从 MySQL 8.0 到 MySQL 5.7 的复制.在某些情况下,使用此配置可能会有所帮助.例如,在 MySQL 升级的 ...

  3. tp5更新某字段加1_tp5.1 实现setInc字段自动加1

    有了基础页面的支撑,想要提高页面的用户体验,那么异步的数据加载目前来说是最好的处理方式了.Ajax分页是练手的最好应用场景,运用到的知识点,在上节课老友记之PHP7留言板开发(Aj 2020-12-1 ...

  4. sql 批量更新时间字段加小时

    sql 批量更新时间字段加小时 update 表名 set 时间字段=时间字段+12/24 where 条件 sql update su_user t set t.update_time = t.up ...

  5. Fragment的懒加载与生命周期详解

    提示:本文仅为笔者学习记录 Fragment的懒加载与生命周期详解 什么是懒加载 了解Fragment的生命周期 onAttach onCreate onCreateView onActivityCr ...

  6. 一加一 安装 Kali NetHunter 详解

    一加一 安装 Kali NetHunter 详解# 2018年4月20日13:02:44 手机:Oneplus one 软件: Kali NetHunter 工具:一加工具包 解读:手机安装 kali ...

  7. [crypto]-02-非对称加解密RSA原理概念详解

    说明:本文使用的数据来自网络,重复的太多了,也不知道哪篇是原创. 算法原理介绍 step 说明 描述 备注 1 找出质数 P .Q - 2 计算公共模数 N = P * Q - 3 欧拉函数 φ(N) ...

  8. [crypto]-01-对称加解密AES原理概念详解

    1.对称加解密 术语:P是明文,C是密文,K是密钥,E是加密算法,D是解密算 (1).常用的对称加解密有哪些? (2).加解密的模式 [ecb]这种模式是将整个明文分成若干段相同的小段,然后对每一小段 ...

  9. 【胖虎的逆向之路】01——动态加载和类加载机制详解

    胖虎的逆向之路 01--动态加载和类加载机制详解 一.前言 二.类的加载器 1. 双亲委派模式 2. Android 中的类加载机制 1)Android 基本类的预加载 2)Android类加载器层级 ...

最新文章

  1. RabbitMQ管理(5)——集群管理
  2. ajax类型的区别,ajax请求的类型 有post get 请问两种有何区别?
  3. 2021年中国物流地产行业发展报告
  4. Seata多微服务互相调用_全局分布式事物使用案例_Order-Module order微服务的配置搭建_写代码上---微服务升级_SpringCloud Alibaba工作笔记0061
  5. 论文《Learning Spatial Fusion for Single-Shot Object Detection》解读
  6. send的内容ajax,Ajax中send方法的使用
  7. echarts+php+mysql 绘图实例
  8. java期末考试试卷及答案文库_《java语言程序设计》期末考试试题及答案(题库超级大全-应考必备)java考试题必从中出...
  9. js 修改html编码,Javascript 中对HTML编码和解码的方法
  10. 密码编码学与网络安全笔记(第7版)
  11. 大揭秘(1):网店背后的隐秘产业链【连载】
  12. UE 4.13 3D Widget使用
  13. delphi异步与javascript
  14. NVIDIA GEFORCE 2080 / 2080 SUPER / 2080 Ti + CUDA Toolkit 8.0 深度学习模型加载速度慢
  15. 第十一天: SD卡原理分析及SD卡启动详解
  16. 关于openfire支持视频聊天
  17. python opengl 教程_OpenGL新手和弃用
  18. java相关面试总结
  19. Unity3D 自学之路
  20. 什么是超链接伪类和伪元素

热门文章

  1. PICRUSt2软件
  2. TiP:湖大于峰组综述​病原体分泌的宿主模拟物在植物病害发展中的新作用!...
  3. 【LorMe云讲堂】梁玉婷:农田土壤微生物共存与功能识别调控
  4. MPB:林科院袁志林组-​杨树根系-真菌互作体系构建方法
  5. Microbiome:根系分泌物驱动土壤记忆抵御植物病原菌
  6. h5在线浏览word_怎样将PDF在线转换成Word?教你成为一个高手的方法
  7. python使用matplotlib可视化3D曲面图、曲面图表示一个指定的因变量y与两个自变量x和z之间的函数关系
  8. R语言ggplot2可视化指定保存到pdf的图像的具体尺寸、保证缩放的一致性:使得绘图元素(文本、点大小等)在设计上都具有相同的绝对大小、设置全局数据点大小、主题格式、设置图像保存的具体尺寸
  9. R语言apriori算法进行关联规则挖掘(限制规则的左侧或者右侧的内容进行具体规则挖掘)、使用subset函数进一步筛选生成的规则去除左侧规则中的冗余信息、获取更独特的有新意的关联规则
  10. R语言构建xgboost模型:交叉验证(cross validation)训练xgboost模型