Mysql使用函数后不走索引怎么优化?

news2024/11/25 16:56:56

网上很多人说mysql一旦使用函数就不走函数,但是事实真的是如此吗?我先说明,并不是如此的,本篇文章会通过DAYOFWEEK()substr()两个函数作为条件查询,看看究竟是否会走索引(其他函数同理),使用函数不走索引的时候又应该如何做sql优化,本篇文章重点是基于这两点进行分析。

目录

    • 一、什么场景下使用函数索引会失效?
    • 二、索引失效了应该怎么处理?
      • 1.通过【sql优化】让索引生效
      • 2.通过【虚拟列】让索引生效
    • 三、总结

一、什么场景下使用函数索引会失效?

测试数据如下:

create_time和name列是都建立了索引的。

DROP TABLE IF EXISTS `demo`;
CREATE TABLE `demo`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `create_time` datetime NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `create_time`(`create_time`) USING BTREE,
  INDEX `name`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = DYNAMIC;


INSERT INTO `demo` VALUES (1, '2023-04-28 10:41:16', 'zhangsan');
INSERT INTO `demo` VALUES (2, '2023-04-01 10:41:22', 'lisi');

DAYOFWEEK():函数返回日期的工作日索引值,即星期日为1,星期一为2,星期六为7。 这些索引值对应于ODBC标准。

通过下面会发现一个问题,假如是select * 的情况下是不会走索引的,假如是只返回使用函数的列是会走索引的。

EXPLAIN SELECT * from  demo WHERE dayofweek(create_time) = 6 \G;

EXPLAIN SELECT dayofweek(create_time),create_time from  demo WHERE dayofweek(create_time) = 6 \G;

在这里插入图片描述

关于执行计划的解读:

在这里插入图片描述

截取字符串语法:substr(obj,start,length)

参数:

  • obj:从哪个内容中截取,可以是数值或字符串。
  • start:从哪个字符开始截取(1开始,而不是0开始)
  • length:截取几个字符(空格也算一个字符)。

通过下面案例会发现,跟上面的案例是一样的,同样是select * 的情况下是不会走索引的。

EXPLAIN SELECT *  from demo WHERE substr(name,1,3) = 'lis'\G;

EXPLAIN SELECT substr(name,1,3),name,id  from demo WHERE substr(name,1,3) = 'lis'\G;

在这里插入图片描述

二、索引失效了应该怎么处理?

1.通过【sql优化】让索引生效

那么问题来了遇到这种查询所有数据使用函数不走索引的我们应该如何优化。通过以下试验发现可以携带id,id是主键的情况下不会导致索引失效!

EXPLAIN SELECT substr(name,1,3),name,id,create_time  from demo WHERE substr(name,1,3) = 'lis'\G;

EXPLAIN SELECT substr(name,1,3),name,id  from demo WHERE substr(name,1,3) = 'lis'\G;

通过以下试验得出结论,假如使用函数作为条件查询,只能返回条件的那一列跟id主键列,一旦返回其他的列就会索引失效!

在这里插入图片描述

由此优化方案便出来了,假设我们要查name列当中前三个字母是lis的全行数据,然后我们想让他使用到索引,可以使用嵌套查询的方案:

这里进行提示以下:MySQL的IN运算符可以使用索引,但是,有一点需要注意。如果你的IN子句中包含的值很多,那么MySQL可能会选择不使用索引,因为扫描大量的值可能比使用索引更快。这个阈值通常是1000个值,但这个值是可配置的。表内数据太少使用IN也不会使用索引!

EXPLAIN SELECT * FROM demo WHERE id in (SELECT id  from demo WHERE substr(name,1,3) = 'lis') \G;

如下案例显示实际上并未使用到索引

在这里插入图片描述
上面测试的表当中就两条数据所以显示的in并没有使用索引,如下表内共有一万条数据,然后对主键使用in查询,可以很明显的看到,是使用了索引的。由此可证明in是会使用索引的,只不过mysql会根据权衡利弊到底使用索引快还是不使用索引快。

在这里插入图片描述

2.通过【虚拟列】让索引生效

Mysql 5.7 中推出了一个非常实用的功能 虚拟列 Generated (Virtual) Columns

  • InnoDB支持在虚拟生成的列上建立二级索引。不支持其他索引类型(主键索引)。在虚拟列上定义的二级索引有时也称为“虚拟索引”。
  • 二级索引可以在一个或多个虚拟列上创建,也可以在虚拟列与常规列或存储生成列的组合上创建。包含虚拟列的二级索引可以定义为UNIQUE
  • 当在虚拟列上使用辅助索引时,由于在INSERT和UPDATE操作期间在辅助索引(辅助又叫二级索引)记录中实现虚拟列值时执行计算,因此需要考虑额外的写成本。即使有额外的写成本,虚拟列上的二级索引也可能比生成的存储列更可取,生成的存储列在集群索引中具体化,从而导致需要更多磁盘空间和内存的更大的表。如果没有在虚拟列上定义二级索引,则会产生额外的读取成本,因为每次检查列的行时都必须计算虚拟列值。

语法:ALTER TABLE 表名称 add column 虚拟列名称 虚拟列类型 GENERATED ALWAYS as (表达式) [VIRTUAL | STORED];

MySQL 在处理 虚拟列存储问题的时候有两种方式:

  • VIRTUAL(默认):不存储列值,在读取表的时候自动计算并返回,不消耗任何存储,这种存储方式仅 InnoDB 支持设置索引。
  • STORED:在插入或更新时计算存储列值,存储的虚拟列需要存储空间,并且 MyISAM 也可以设置索引。

在这里插入图片描述

下面我们基于substr(name,1,3)函数来创建一个虚拟列:

ALTER TABLE demo add column virtual_name VARCHAR(5) GENERATED ALWAYS as (substr(name,1,3)) VIRTUAL;

对虚拟列添加索引:

ALTER TABLE `demo`.`demo` 
ADD INDEX `virtual_name`(`virtual_name`) USING BTREE;

这时候就可以直接通过虚拟列来完成查询操作了

 EXPLAIN SELECT *  from demo WHERE virtual_name = 'lis';

在这里插入图片描述

三、总结

假如使用函数作为条件查询,只能返回条件的那一列跟id主键列,一旦返回其他的列就会索引失效!针对于使用函数索引失效问题,可以使用嵌套查询来解决,也可以使用虚拟列来解决!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/471948.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

15.基于主从博弈的智能小区代理商定价策略及电动汽车充电管理

说明书 MATLAB代码:基于主从博弈的智能小区代理商定价策略及电动汽车充电管理 关键词:电动汽车 主从博弈 动态定价 智能小区 充放电优化 参考文档:《基于主从博弈的智能小区代理商定价策略及电动汽车充电管理》基本复现 仿真平台&#…

【ChatGPT】如何修复access denied you do not have access to chat.openai.com

文章目录 一、前言二、是什么导致 ChatGPT 访问被拒绝错误?三、如何修复 OpenAI 上的访问被拒绝?3.1 清除 Cookies 和缓存3.2 检查账户登录凭证3.3 允许请求的权限3.4 从其他浏览器登录OpenAI3.5 联系 OpenAI 客户支持 四、ChatGPT 支持的国家和地区 一、…

delphi使用Edge Browser浏览器组件

RAD Studio 10.4在VCL Web浏览器上具有一项新功能。它是Edge Browser,它具有新功能,并且比以前的Web浏览器更具兼容性。 这是在C Builder和Delphi中使用Edge浏览器的快速帮助。 在Windows上安装“ Edge ”版本从RAD Studio的GetIt菜单下载“ Edge SDK…

JMeter的使用(二)

九、直连数据库 通过直连数据库让程序代替接口访问数据库,如果二者预期结果不一致,就找到了程序缺陷。 获取某条学院的名字,放在百度搜索: JMeter 不具备直连数据库功能,必须整合第三方(jar包)实现配置数据库的连接通过JDBC Re…

token 登录流程

客户端用账号密码请求登录服务端收到请求,验证账号密码验证成功后,服务端签发token,发送给客户端客户端收到token,保存下来客户端每次向服务器发送请求资源,都携带token服务器验证token验证成功,返回资源

LINUX文件管理与编辑命令2

文章目录 一、LINUX文件管理与编辑命令总结 一、LINUX文件管理与编辑命令 Linux wc命令:统计字节数、字数、行数 Linux echo命令:输出字符串或提取Shell变量的值 Linux chmod命令:权限管理 Linux chown命令:修改文件或目录的所有者或所属组 Linux whereis命令:查找文件 Linux …

揭秘长尾关键词的力量:如何在搜索引擎上挤掉竞争对手?

现在,你已经掌握了SEO 的流程,知晓了网站优化的各种方法,也清楚了站外优化的技巧,但问题又来了:你知道优化网站,竞争对手也知道;你懂得站外优化,竞争对手也懂。在这种情况下&#xf…

AI工具究竟是帮手还是对手?

本文概要 近日育碧开发了人工智能工具 Ghostwriter,可以一键生成游戏NPC对话。不少游戏开发者担心AI写手工具的出现会让自己“饭碗”不保,但Swanson表示这个工具只是为了提供第一稿的 barks来减少对话生成工作的繁琐度。AI工具究竟是帮手还是对手&#x…

C++笔试笔记1(4399 西山居 深信服 剑心互娱 快手)

写在前头,这里面只是我在做这些公司笔试时抄下来的一部分题,并不全,但我会尽量把我所抄的每道题的知识点都贴上 1. Linux下支持的IO多路复用,有selec、poll和epoll,但Windows下仅支持select。 2. 新版C,智…

OpenGL(一)——初识和搭建

目录 一、前言 二、概述 2.1 光学 2.2 三通道 2.3 上下文Context 2.4 渲染管线 2.5 着色器Shader 2.6 缓冲区和数组 三、安装 四、运行 五、库API 5.1 核心库GL 5.2 实用库GLUT 一、前言 渲染render是用软件从模型生成图像的过程,也表示编辑视频生成想达…

2023年第二十届五一数学建模竞赛题目 B题超详细思路

详细思路以及发布视频版,大家可以去观看,这里是对应的文字版,内容相差不多。 B题:快递需求分析问题 B题的问题难度不大,难点就在于后几问的模型求解。问题多、模型多、冗杂,就是B题的特点。 难度 A>B…

代码随想录训练营day56|583、两个字符串的删除操作;72、编辑距离;编辑距离总结篇

583、两个字符串的删除操作 给定两个单词 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步数,每步可以删除任意一个字符串中的一个字符。 示例: 输入: "sea", "eat"输出: 2解释: 第一步将"sea"变…

vue3之vite创建h5项目1(创建vite项目、配置IP访问项目、配置多环境变量与预览打包生产效果、配置别名)

目录 vue3之vite创建h5项目101:创建vite项目02:配置IP访问项目 vite.config.ts03:配置多环境变量03-1:配置多环境变量之dev环境 .env.development03-2:配置多环境变量之test环境 .env.test03-3:配置多环境变…

精彩!openEuler 社区年度顶级会议发生了啥?

2023年4月20-21日,万涓汇流,奔涌向前,openEuler Developer Day2023(以下简称“ODD2023”)在上海以线上线下的方式圆满举办。 本次大会由开放原子开源基金会指导,中国软件行业协会、openEuler社区、边缘计算产业联盟共同主办&#…

移动端Touch事件点击穿透

文章目录 移动端Touch事件点击穿透问题原因解决阻止默认行为目标元素延迟隐藏 移动端Touch事件点击穿透 问题 在发生触摸动作约300ms之后,移动端会模拟产生click动作,如果touch事件隐藏了原来元素 则click总作用到它底下的具有点击特性的元素&#xff…

高铁列车粒子群算法及改进粒子群算法多目标单目标运行优化设计

问题介绍 根据表1、2、3 所列数据,以能耗、运行时间、舒适性为目标分别设计列车运行速度—距离曲线;完成单目标以及多目标优化下的列车运行对比;选择其中一种方案,设计列车速度跟踪控制算法并进行性能分析。 1 列车参数设置表优化…

陶渊明最有名的10首诗,闲适美好

他是中国第一位田园诗人,被誉为“古今隐逸诗人之宗”、“田园诗派之鼻祖”。 他是诗人、辞赋家、散文家。 他是陶渊明。 欧阳修:晋无文章,唯陶渊明《归去来兮辞》。 陶渊明不为五斗米折腰,挂冠而去,给后世留下一段…

浅谈软件测试工程师的技能树

软件测试工程师是一个历史很悠久的职位,可以说从有软件开发这个行业以来,就开始有了软件测试工程师的角色。随着时代的发展,软件测试工程师的角色和职责也在悄然发生着变化,从一开始单纯的在瀑布式开发流程中担任测试阶段的执行者…

基于H3Core分区的司机轨迹实时存储-技术方案

1、背景 由数据分析师提出的需求,需要分析每10s各个区域(颗粒度到H3Code 8级 面积约0.7平方公里)的司机分布情况,实现准实时的区域司机分布。 H3Code的概念可以参考以下博客: Uber H3简单介绍_Scc_hy的博客-CSDN博客…

【Python学习 】Python的模块或py文件导入

目录 一、前言 二、python项目中导入模块(py文件)的几种方式 1、直接将py文件放到默认的库位置(特点:高效) 2、将文件放到创建的库位置(特点:方便管理) 3、将模块(模…