记一次MySQL的优化案例
作者:yangyidba 发布时间:2024-01-14 21:32:58
一 背景
有赞的每个OLTP数据库实例上会设置一个sql-killer进程用于kill 掉执行时间超过一定阈值的sql。下午开发接收到sql被kill的报错,一起帮助开发排查,本文介绍该案例。
二 场景分析
表结构:
CREATE TABLE `xxx_info` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`user_id` bigint(20) unsigned NOT NULL DEFAULT '0' ,
`group_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`nick_name` varchar(30) NOT NULL DEFAULT '' COMMENT '昵称',
`is_del` tinyint(5) NOT NULL DEFAULT '0' COMMENT '0:数据有效、1:数据逻辑删除',
`created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `idx_userid_groupid` (`user_id`,`group_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1382032 DEFAULT CHARSET=utf8mb4 ;
问题sql如下
SELECT id, name,status FROM xxx_info WHERE user_id IN (670039223,'373149878') AND group_id = 1 AND is_del = 0;
第一眼看到sql ,先检查了表结构 和索引 user_id 是数值类型的,且索引ok 然后手工执行计划竟然没有走idx_userid_groupid索引,
怀疑 user_id in 两种不同类型的字段导致"隐式转换",将 其中参数值都换为数值类型或者字符串 或者使用 user_id=数值类型 or user_id=字符串,再次执行
执行计划都是正确。对此我们要解决两个问题
那么为啥当user_id in (X,Y,Z) 是不同类型时,就不走索引了呢?
我们使用optimizer_trace 来跟踪执行计划。
set session optimizer_trace='enabled=on';
SELECT id, nick_name,is_del FROM xxx_info WHERE user_id IN (670039223,'373149878') AND group_id = 1 AND is_del = 0;
select * from information_schema.optimizer_trace;
SELECT id, nick_name,is_del FROM xxx_info WHERE user_id IN (670039223,'373149878') AND group_id = 1 AND is_del = 0;
select * from information_schema.optimizer_trace;
set session optimizer_trace='enabled=off';
获取两个sql的执行计划并对比,结果显示
看到结果我表示
翻阅 https://bugs.mysql.com 还没找到相关结果。
代码里面如何产生不同类型的值?
以下是开发(阿杜)自己的测试
目前的解决方式是和开发同学沟通让他们在程序做参数类型一致性校验,都转换为 int/long 类型。
特别提醒常见发生隐式转换导致索引失效的场景
1 where 判断符号左边是字符串 ,右边是数值 比如
where name = 123
2 多表join关联条件的字段类型不一致,类似于 1
3 多表join关联条件字符集类型不一样。比如
a 表 order_no 是utf8mb4 ,b 表order_no 是 utf8
感兴趣的 朋友可以多测试,有其他案例的 欢迎讨论。
来源:https://mp.weixin.qq.com/s?__biz=MzI4NjExMDA4NQ==&mid=2648450549&idx=1&sn=475067207fc111af7244570b9014f87a&chksm=f3c97d1fc4bef409924c983edc7010b8c9c5427090ef2e6bc964fc6d118fd830635eeac42493&scene=21#wechat_redirect


猜你喜欢
- 写给新手的话pycharm是什么,为什么让我指定interpreter记事本最开始写C语言代码的时候,人们使用vi,记事本等软件写代码,写完
- Click 是用 Python 写的一个第三方模块,用于快速创建命令行。我们知道,Python 内置了一个 Argparse 的标准库用于创
- 本文实例讲述了Python实现判断并移除列表指定位置元素的方法。分享给大家供大家参考,具体如下:问题很简单,输入一个列表和索引,若索引超出列
- 这个函数是前几年刚流行小偷程序的时候,偶写来用于小偷程序中截取代码的;可能有些朋友在我以前的代码中看见过了,但没有写用法,现在把调用方法及使
- 本文实例讲述了python通过exifread模块获得图片exif信息的方法。分享给大家供大家参考。具体分析如下:python可通过exif
- 本文实例为大家分享了微信小程序定时拍照的具体代码,供大家参考,具体内容如下在某些进行签到的场景,为了防止用户选择相册的照片或者不实时拍照,设
- 为了降低用户注册难度,国际站的主注册表单一直在改进。主注册三月至今发生了两次较大的变化,现在对表单调整的地方分解如下:1. 两步
- ASPError Object 这个新增的,内置与ASP 3.0中的对象提供了一个以往版本中没有的专门用来处理错误的对象,这样,我们来操纵错
-   在用Python进行数据处理的时候,经常会遇到DataFrame中的某一列本应该是数值类型,但由于数
- element-ui中el-select下拉框选项过多el-select中options数据超过3000条就会造成前端页面明显卡顿,本次我的
- 常见的绑定事件有直接绑定在页面元素中比如<div id="wrap" onclick="a();&quo
- 例子:http.Handle("/tmpfiles/", http.StripPrefix("/tmpfile
- 一、什么是类类(class),作为代码的父亲,可以说它包裹了很多有趣的函数和方法以及变量,下面我们试着简单创建一个吧。这样就算创建了我们的第
- 执行文件和目标导入模块在同一目录直接import比如我要在ma_main.py中导入env包中的make_env.py文件, 从而读取其中的
- 引用Nmap库实现扫描功能,本节课比较简单一看就会。编写环境:Python2.x编写:首先安装Nmap程序,并添加环境变量pip insta
- 已经获取微信公众号发布的图片,但不能正常显示 ,提示:此图片来自微信公众平台 未经允许不得引用。 这是怎么回事呢?遇到这
- mysql数据库开机报错: InnoDB: The log sequence number in ibdata files does not
- 直接使用==比较的情况分类说明是否能比较说明基本类型整型( int/uint/int8/uint8/int16/uint16/int32/u
- 概述:each() 方法规定为每个匹配元素规定运行的函数。返回 false 可用于及早停止循环,相当于break。返回 true 可以结束本
- 这篇日志完全是看了一篇日志后的启发,原文为: * 的eval和new Function。很少使用new Array的方式来定义数组,没想到ne