暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

慢SQL导致mysql被OOM

原创 问题归档 2019-03-20
1263

问题描述

各位老师,请教一个问题 ,我在mysql服务器上本地登录,执行了一个SQL(select  b.id,b.status from  rb_bak b   where  id not  in (select  id from rb );该语句问了找不同数据, rb和 rb_bak 数据量均为500万左右),SQL很慢,30分钟也没结果;

在SQL语句执行期间,发生了OOM,mysql服务被kill。查看系统日志发现 mysqld 占用内存基本没有变,但是本机连接mysql的客户端进程(5733)却占用了内存近20G,这很让人费解,SQL没有执行完,客户端怎么会占用这么多内存?

用其他SQL查询查询不同数据,也就十几条数据,更不可能占用这么多内存呀。还请各位老师帮忙分析一下,谢谢。

系统日志如下:

Jan 17 23:52:27 prod-mysql-01 kernel: [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
Jan 17 23:52:27 prod-mysql-01 kernel: [125254]     0 125254    27087        5   0       0             0 mysqld_safe
Jan 17 23:52:27 prod-mysql-01 kernel: [126004]   498 126004 24974389 22439356   5       0             0 mysqld
Jan 17 23:52:27 prod-mysql-01 kernel: [ 5733]     0  5733  7606586  6077037   7       0             0 mysql
kernel: Out of memory: Kill process 126004 (mysqld) score 743 or sacrifice child
kernel: Killed process 126004, UID 498, (mysqld) total-vm:99897556kB, anon-rss:89753492kB, file-rss:3928kB

专家解答

客户端内存OOM的话,一般是客户端接收到结果集很多的情况。

两个表都是500万左右的数据,使用not in肯定会出现性能问题,把库搞死也是有可能的。首先把not in子查询select  id from rb查出来的500多万个结果放到内存,然后再从rb_bak表中取ID,用500多万个ID去遍历内存中的子查询结果,自然就会消耗很多内存

两个大表尽量不要使用not in,改为not exists

select  b.id,b.status from  rb_bak b where not exists (select  1 from rb r where b.id=r.id)
最后修改时间:2019-04-03 22:14:52
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论