1、发现问题
昨天跟踪线上慢SQL,发现有一条SQL始终走全表扫描,造成查询非常慢,查询时间达到了10分钟。
2、问题复现
SQL语句非常长。估计有上百行。这里就不贴原语句了,通过分析,找到了根本原因,我这里利用MySQL demo库sakila来重现
有如下语句
explain
SELECT
COUNT(*) FROM PAYMENT
where staff_id in(1,2)
and rental_id in (41,42,43,44)
and customer_id in(39,40,41,42,43,44,45,46);
复制
查看执行计划。走的是全表扫描。
查看该表结构
show create table PAYMENT;
复制
我where 条件的三个字段都有索引 ,为什么该语句会走全表扫描呢?
当时我在生产环境是百思不得其解。找了好久好久原因。这里就直接的揭晓原因
explain 后去执行show warining;
show warnings;
复制
可以看到,除了改写的语句,还有一条警告,正是由于这个警告是造成全表扫描的根本原因。
生产环境是由于SQL太长,已超过了range_optimizer_max_mem_size默认值,在这里为了好重现。我改变了range_optimizer_max_mem_size的值
SET @@SESSION.range_optimizer_max_mem_size = 500;
复制
用SET_VAR Hint其实更好观察这个问题
explain
SELECT
/*+
SET_VAR(range_optimizer_max_mem_size = 500)
*/
COUNT(*) FROM PAYMENT
where staff_id in(1,2)
and rental_id in (41,42,43,44)
and customer_id in(39,40,41,42,43,44,45,46);
复制
当range_optimizer_max_mem_size = 500 时全表扫描
explain
SELECT
/*+
SET_VAR(range_optimizer_max_mem_size = 5000)
*/
COUNT(*) FROM PAYMENT
where staff_id in(1,2)
and rental_id in (41,42,43,44)
and customer_id in(39,40,41,42,43,44,45,46);
复制
当range_optimizer_max_mem_size = 5000 时 正常走了索引
这里我发现一个官方文档的错误。官方文档指出 range_optimizer_max_mem_size 不支持 SET_VAR,但上面可以看出我实际操作是可以用SET_VAR的。
这里官方文档明显错了。各位大佬可自行尝试。我测试的版本为 8.0.32
具体range_optimizer_max_mem_size 变量相关与范围优化说明可参见文末官方文档链接。
最后修改时间:2023-07-26 09:55:12
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
文章被以下合辑收录
评论
其中范围访问方法有一个候选关键字,
每个与OR组合的谓词使用大约230个字节
每个与AND组合的谓词使用大约125个字节
in()列表中的每个文字值都算作与OR组合的谓词。如果有两个IN()列表,则与OR组合的谓词数量是每个列表中文字值数量的乘积。因此,在前面的情况下,与OR组合的谓词的数量是M×N。
这算法真麻烦!
1年前

评论
range_optimizer_max_mem_size 默认值是8K. 那怎么算一个SQL占用内存多少呢? 还是算SQL总长度? 会涉及字符集大小吗?
1年前

1
相关阅读
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1270次阅读
2025-03-13 11:40:53
MySQL8.0统计信息总结
闫建(Rock Yan)
482次阅读
2025-03-17 16:04:03
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
453次阅读
2025-03-13 14:38:19
Ogg23ai高手必看-MySQL Innodb Cluster跟oracle的亲密接触
曹海峰
448次阅读
2025-03-04 21:56:13
SQL优化 - explain查看SQL执行计划(一)
金同学
387次阅读
2025-03-13 16:04:22
MySQL突然崩溃?教你用gdb解剖core文件,快速锁定“元凶”!
szrsu
333次阅读
2025-03-13 00:29:43
MySQL生产实战优化(利用Index skip scan优化性能提升257倍)
chengang
325次阅读
2025-03-17 10:36:40
一键装库脚本3分钟极速部署,传统耗时砍掉95%!
IT邦德
233次阅读
2025-03-10 07:58:44
MySQL数据库当前和历史事务分析
听见风的声音
228次阅读
2025-04-01 08:47:17
MySQL8.0直方图功能简介
Rock Yan
224次阅读
2025-03-21 15:30:53