数据库 - mysql从一张表更新另一张表,如何效率最高?
黄舟
黄舟 2017-04-17 11:46:45
[MySQL讨论组]

最近工作上遇到的问题,有条sql语句执行时间一直很长,情况如下:
a表记录电话通话情况的表,b表记录的是电话通话失败的原因,两表之间通过一个叫sessionid的字段关联在一起。两表结构大致如下:

## a 表:##
===========
id, 主键,自增
caller --> 主叫号码
callee --> 被叫号码
state  --> 通话结果,成功=1,失败=2
sessionid --> 唯一标志一通电话的标记位
fail_reason --> 电话通话失败原因
send_time --> 电话拨号的时间,unix时间戳

------------------------------------

## b 表:##
===========
id --> 主键,自增id
reason  --> 电话通话失败的原因
sessionid --> 唯一标志一通电话的标记位
create_time --> 记录创建时间

a表记录大概50W条,b表记录大概20w条,且b表中存在sessionid重复的记录
由于某些原因,a失败原因字段不能关联b表查询得到,而要定期(30分钟或1个小时)从b表更新过来,这个更新语句该如何写效率最高?
最初我的写法是这样:

update a表 t 
============
set t.fail_reason  =  (SELECT t2.reason from   b表 t2 
        where t.sessionid = t2.sessionid 
        and t.status = 2 
        order by t2.create_time desc 
        limit 0,1
        )
where t.status = 2 
and UNIX_TIMESTAMP() -t.send_time < 3600 
and (t.fail_reason = '' or t.fail_reason is null)

以上语句写成数据库事件,每隔半个小时执行一次,后期随着数据增大,感觉效率非常低,执行一次最少都几十分钟,
后来百度google到另一种写法:

update a表 t ,b表 t2
=====================
set t.fail_reason=t2.reason
where t.sessionid=t2.sessionid
and t.status=2
and UNIX_TIMESTAMP() -t.send_time < 3600 
and (t.fail_reason = '' or t.fail_reason is null)

但还是很慢

请问这类逻辑,mysql中sql语句有什么好的写法吗?
还是我该去考虑增加索引,或者做数据拆分了?

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回复(3)
迷茫
  1. 分拆sql。 复杂的sql,很容易导致数据库性能的急剧下降。可以考虑先查出当前一个小时内a表失败的, 通过脚本循环:每次查询一条sessionid失败的原因,再更新到a表, 然后再循环处理下一条。虽然看似不如一条大sql 来的简单, 但这样降低了数据库计算的复杂性和消耗, 很多时候会很好的提升效率

  2. 优化复杂sql。 可以通过explain, 查看sql是否恰当的使用了索引, 同时应该尽量优先缩小结果集。

建议题主分拆 sql吧, 看看能不能获得想要的性能

怪我咯

在没有遇到写锁队列之前,总觉得联表更新是极好的。现在总觉得,分拆SQL+缓存+异步是极好的。

ringa_lee

在v2ex上看到有朋友说通过添加索引与使用临时表的方法,尝试了一下,效率确实有很大提高。
主要思路就是将数据从b表提取出来,存放到临时表c(字段为session,fail_reason)
然后通过 update a,c set a.fail_reason = c.fail_reason where a.session=b.session
几十万的数据也只要十几秒就更新完成。
谢谢楼上几位给出的思路:)

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号