PHP执行大规模任务时如果提升效率?
巴扎黑
巴扎黑 2017-04-11 10:11:22
[PHP讨论组]

我有一个php,每天计划任务执行一次,逻辑如下:
1.连接数据库,从数据库中Select读取相关数据到数组
2.根据得到的数据数量进行循环,循环中间包含3个mysql操作(select、insert、update各一个)
3.循环完后关闭数据库连接

循环执行的次数根据步骤1的mysql_num_rows而定,基本上几千上万。
那么在循环过程中就会短时间内连续执行几千上万X3次数据库操作,效率非常低下。并且因为循环次数多任务重需要很长时间才能执行完,会导致nginx出现504错误。
且频繁数据库操作和长连接,占用过多资源,导致整个环境效率低下。

请问该怎么优化呢?
麻烦各位大神赐教,先谢谢了

巴扎黑
巴扎黑

全部回复(10)
PHP中文网

就你说的这个情况,建议不要用请求的方式解决,用 crontab 加计划任务在后台运行 php 脚本,数据库查询时分批处理,比如总共 100000 条,每次 1000 条;如果必须逐条处理且速度不是很快,建议一边 fetch_row 一边处理,避免先放入 array 再循环。记得根据执行情况 set_time_limit 和数据库连接的超时时间。

PHP中文网

大量数据的时候交由任务系统去执行。首先发起一个请求,由消息生产者将请求交给消费者处理,并返回,避免等待出现超时。消费者执行多线程处理。建议使用Gearman,使用起来很方便,而且支持PHP接口。其它的类似Workman,Swoole等都能实现。

巴扎黑

所有的操作都集中在同一台服务器上的同一个时间点执行, 肯定是耗时又耗资源的.
要么像 @黄弘 说的,分批次处理.
要么就增加服务器, 把这些任务分布到其他的服务器上执行, 所谓分布式处理, 但是又会增加任务的复杂度, 因为还要保证数据的一致性

阿神

1.导出数据到文件,读文件去循环。(比如mysqldump)
2.考虑是否可以先拼语句,批量执行。而不是每个循环都执行。
3.考虑是否可以用存储过程

并且因为循环次数多任务重需要很长时间才能执行完,会导致nginx出现504错误。

难道是实时计算?计算量大的任务是否考虑后台跑任务计算好写入缓存,实时请求只读缓存。

巴扎黑

这个问题有一点像我之前回答的那个并行执行提高效率的问题

本质就是针对读这个大数据进行分流,按ID进行取模并行执行,比如你的服务器和数据库能承受20个并发执行

那并行的最简单方式就是开20个脚本进程执行
0.php -> select * from test where id%20=0;
1.php -> select * from test where id%20=1;
2.php -> select * from test where id%20=2;
....

这个是拉的方式。

还有一种方式是推到队列,队列再调用woker进程去执行,这样更规范化好管理,比如楼上有一个提到的gearman,我之前在做短信平台的时候也有每日定时任务,就是用的这个。

逻辑大概是你开一个定时任务脚本把所有查询出来的数据通过调用gearman客户端把数据任务发到gearman调度器,然后你开20个woker(可以在同一台服务器也可以在局域网内的不同服务器),然后调度器就会分配给这20个gearman woker脚本去执行,每个worker脚本代码一样,是一条数据一个任务的执行

PHP中文网

用cli模式的PHP脚本处理即可,不要使用WEB方式,很容易超时

怪我咯

会导致nginx出现504错误

直接跑脚本

PHPz

看看能不能把任务搞成队列的形式来处理,一次只处理一小部分,分时段处理

PHPz

存储过程比用PHP快无数倍

天蓬老师
  1. 一次不要取太多的数据(减少资源占用)

  2. 采用多进程的方式,并行执行(提高效率)

  3. 适当的使用 sleep

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

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