首页 > 数据库 >Mysql 系列 | 性能优化 - 函数调用

Mysql 系列 | 性能优化 - 函数调用

时间:2022-10-16 17:22:24浏览次数:51  
标签:where 函数调用 索引 Mysql tid NULL 优化 id select

sql 性能优化,是代码编写过程中必定要考虑的内容,弄懂性能背后的逻辑,起到事半功倍的效果。

今天学习几种常见的简单优化场景。


条件字段中调用函数

以公司的打卡信息表为例,表中存放了公司近三年的打卡记录,add_time 字段有索引。
查询自己每年 7 月份的打卡情况, select count(*) from works where month(add_time) = 7;

  • 发现执行了很长时间才返回结果,是因为 Mysql 中,对字段做了函数处理,就用不上索引了。

  • 如下图,add_time 的索引图

    • 如果使用 2018-7-1 条件查询,引擎可以按照图中箭头快速定位到所需要的结果。因为 B+ 树中,同一层兄弟节点是有序的。

    • 如果按照 month(2018-7-1) 查询的话,当传入条件 7 的时候,在树的第一层就不知道该怎么往下找了。破坏了索引值的有序性,因此优化器决定放弃走树索引。
      image

  • 条件字段加了函数处理后,破坏了索引有序性,这时优化器会选择其他方案。比起主键索引,add_time 索引更小,所以最终还是会选择 add_time 索引,但是会扫描索引的所有值。为了使用索引的快速定位功能,尽量避免破坏索引有序性。

  • 即使不改变索引的有序性,有时候也会出现问题。 select * from t where id + 1 = 1000,这种时候优化器也不会用 id 索引快速定位到 999 行。要改成 where id = 1000 - 1

隐式类型转换

select * from t where tid=110717;

  • tid 有索引,但 eplain 结果显示,进行了全表扫描。此时你会发现,tid 定义的字段类型是 varchar(32),而输入的参数却是整型。因此需要做类型转换。

  • 此时实际的 sql 就是,select * from t where CAST(tid AS signed int) = 110717。和第一种情况相同,对字段做函数处理,优化器放弃了树索引。

隐式字符编码转换

这种情况常在连表查询的时候常见,表 t、d 中 tid 都设置了索引。

select d.* from t, d where d.tid = t.tid and t.id = 2

  • explain 结果显示如下:

    • 优化器先在 t 表上查到 id=2 的行,使用主键索引,扫描一行。

    • 根据关联字段 tid 去表 d 中查找,第二行 key=NULL,进行了全表扫描

    mysql> explain select d.* from t, d where d.tid = t.tid and t.id = 2 \G;
    *************************** 1. row ***************************
             id: 1
      select_type: SIMPLE
            table: t
       partitions: NULL
             type: const
    possible_keys: PRIMARY,tid
              key: PRIMARY
          key_len: 4
              ref: const
             rows: 1
         filtered: 100.00
            Extra: NULL
    *************************** 2. row ***************************
               id: 1
      select_type: SIMPLE
            table: d
       partitions: NULL
             type: ALL
    possible_keys: NULL
              key: NULL
          key_len: NULL
              ref: NULL
             rows: 11
         filtered: 100.00
            Extra: Using where
    
  • 很明显,表 d.tid 的索引没有用上。此时,检查表定义语句发现,两张表的字符集不同。一个是 utf8,另一个是 utf8mb4

  • utf8mb4 是 utf8 的超集,语句中需要先转换成一致的,才能进行比较。 ... where CONVERT(d.tid USING utf8mb4) = t.tid ...。又同第一种情况,经过函数处理后,优化器放弃了树索引。

  • 这时,常见的优化方案是将两个字符集都改为 utf8mb4

  • 如果无法修改字符集,可以调换驱动表和被驱动表,把函数处理作用在参数值上,也可达到优化的效果。

标签:where,函数调用,索引,Mysql,tid,NULL,优化,id,select
From: https://www.cnblogs.com/rendd/p/16796605.html

相关文章

  • MySQL变量的使用
    在mysql文档中,mysql变量可分为两大类,即系统变量和用户变量。但根据实际应用又被细化为四种类型,即局部变量、用户变量、会话变量和全局变量。 一、局部变量mysql局部......
  • Ant design——message防抖优化——富文本的使用——富文本数据的收集——上传图片保
    button按钮有个loading加载态度。加载状态为true则不可点击。通过这个属性来完成项目中的防抖优化const[seachBtn,setSeachBtn]=useState(false)message.error("用户名不......
  • MySQL索引介绍
    索引主要是用来提高数据库的查询效率的,它对指定的列或列的集合生成索引,然后可以通过索引来检索目标数据,就像目录一样,缩小了扫描范围,大大提高了查询效率。如果不使用索引,My......
  • mysql80解决不支持中文的问题
    1.查看mysql80字符集showvariableslike'character_set%';2.修改server编码格式在mysql安装目录下找到my-default.ini文件并复制一份改为my.ini,文件内加入如下设置......
  • 网络优化哪家强,还得看华为云CDN​
    随着网络安全形势日益严峻,CDN作为网络基础设施的重要组成部分,被广泛应用于各类行业。目前,CDN正逐步走向商业化,且随着AI技术在云服务中的应用,CDN也成为企业上云的一大......
  • 高性能图片优化方案
    目录介绍01.图片基础概念介绍1.1图片占用内存介绍1.2加载网络图片流程1.3三方库加载图片逻辑1.4从网络直接拉取图片1.5加载图片的流程1.6Bitmap能直接存储吗1.7Bitma......
  • MySql的学习
    1:什么是数据库:用来存储数据,管理数据(DBDataBase)2:数据库的分类(1)关系型数据库:MySql,SqlServer,DB2,就是表和表之间,行和列之间的关系进行数据存储(2)非关系型数据库:jso......
  • navicat连接mysql数据库提示失败,提示2059错误
    Navicat连接数据库失败,提示2059错误,如下图参考资料发现使用的数据库版本是mysql8版本,不是mysql5.7版本MYSQL新版本(8以上版本)的用户登录账户加密方式是【caching_sha2_passwo......
  • Python MySQL_基础01
    01.示例:使用Python创建MySQL数据库#1.首先创建一个cursor(),然后将SQL命令作为字符串传递给execute()方法importmysql.connectordataBase=mysql.connector.......
  • 【MySQL】实战教程笔记
    序言感谢林晓斌老师,感谢他的教程:https://funnylog.gitee.io/mysql45/MySQL的基础架构主要分为两层服务层连接器:管理连接,验证权限。尽量使用长连接查询缓存:对一个表......