要扫描一次全表,php 对每一行都要批处理一次,如果单个 php 进程把 600 万行载入内存扫描一次全表处理实在太慢,想用多个 php 进程来扫描表:
想用多个 php 进程从 MySQL 中随机取出一些行出来,因为 primary id 不连续,但用 MySQL 的 ORDER BY RAND()慢的令人发指
想快一点也只能用两个 php 进程,一个 ORDER BY id ASC 顺序执行,一个 ORDERY BY id DESC 倒序执行,但两个进程还是太慢
估计表述得不太明白,反正就是怎样能将 mysql 快速截取成一段一段的行,让多个 php 进程去执行?
1
Sornets 2018-08-06 14:14:29 +08:00
一个思路:
记录 id 取余,比如十个进程,就对 10 取余,根据余数查找对应 id,proc_id = rec_id % 10, |
2
z550665887 2018-08-06 14:18:04 +08:00
limit ?
|
3
582033 2018-08-06 14:25:58 +08:00
分页
|
4
Rekkles 2018-08-06 14:29:36 +08:00
PHP 哪有什么多进程 pthread 性能不会有太大的提高 这种东西如果打算用 PHP 做,mysql 和内存 能扛就能做,一次取 1k 条数据(内存够就多取点),处理 ,update,循环
|
5
lihongjie0209 2018-08-06 14:30:57 +08:00
生产者消费者喽
|
6
widdy 2018-08-06 14:34:20 +08:00 2
有这扯淡时间,一个脚本 600w 行早跑完了,为啥不一次取个 1w 条。
|
7
nsxuan 2018-08-06 15:00:43 +08:00
关键是要开启事务
|
9
newtype0092 2018-08-06 15:54:15 +08:00
@widdy 那就来讨论下 6 亿条怎么做嘛,让这个淡扯的有点意义~
|
10
tanszhe 2018-08-06 15:58:00 +08:00
这种简单到爆的问题 就不要来问了
|
11
mumbler 2018-08-06 16:02:37 +08:00
order by id limit 1,10000
order by id limit 10001,10000 order by id limit 20001,10000 order by id limit 30001,10000 这样就可以一万一万读了,和分页一样 |
12
widdy 2018-08-06 16:03:09 +08:00
@newtype0092 , 真这么大,时间来最清晰,php xxoo.php 2017-01 , php xxoo.php 2017-02 ...
|
13
ps1aniuge 2018-08-06 16:06:41 +08:00
一个进程不行,就多个进程。多个进程不行就 n 机子分布。
这里面要有一个队列,分发任务或表 id。根据实际情况,一次分发一百,一千,一万。 |
14
vacker 2018-08-06 16:10:00 +08:00 via Android
用队列,随便多少条都可以
|
15
GGGG430 2018-08-06 16:10:42 +08:00 via iPhone
pcntl,我上周才刚用过,你把行数除以进程数,然后把各个起始 id 传给各个子进程,快的一比
|
16
yuanfnadi 2018-08-06 16:11:33 +08:00
select * from xxx where id > 0 limit 1000
然后取最后一个 ID 为 1022 select * from xxx where id > 1022 limit 1000 想开几个线程都可以。 |
17
GGGG430 2018-08-06 16:13:12 +08:00 via iPhone
不要排序,各个进程处理各自起始 id 部门数据,然后各个进程都每次取 100 条数据作为一个事物提交,但注意 mysql 连接数和执行脚本机器的负载
|
18
dobelee 2018-08-06 16:16:20 +08:00 via Android
600w。。随便跑跑就行,等你写好算法逻辑,10 遍都跑完了。
|
19
jswh 2018-08-06 16:32:51 +08:00
记得别用对象,用数组就行
|
20
InternetExplorer 2018-08-06 16:38:31 +08:00
能不能直接用 sql 处理?
|
21
xmadi 2018-08-06 18:11:39 +08:00 via iPhone
用 limit 效率很低 可以直接先人工查询最大的 id 和最小的 id 然后以十万个 id 间隔分组 很粗糙肯定不均匀但是没有影响 开进程池 每个进程用 where 筛选分组数据进行处理
|
22
bugsnail 2018-08-06 19:39:48 +08:00 via iPhone
|
23
singer 2018-08-06 19:47:37 +08:00 via iPhone
id 放到 redis 的 list,然后多进程拉起来就好了个
|
24
xschaoya 2018-08-06 21:41:24 +08:00
最简单的多进程资源分配啊,简单粗暴的就是主键分段开多进程。高级点的可以用消息队里(生产者消费者类模型)
|
25
GreatHumorist 2018-08-06 22:38:01 +08:00 via iPhone
还是想想直接用 sql 吧,php 弄很麻烦,上周末弄过一个三百万行的匹配,php 遍历到十万左右就很慢了。最后直接用 sql,贼快,加起来不超过 10 分钟
|
26
yangqi 2018-08-06 22:41:32 +08:00
多复杂的处理不能在 mysql 里面完成?
|
27
beastk 2018-08-06 22:45:55 +08:00 via iPhone
要不就用 php 执行个 go 或者 python,分分钟给你跑完
|
28
jsjscool 2018-08-06 23:46:11 +08:00
使用进程间通信也是几句代码的事情。和语言无关,通信的方式无非就是信号量,消息队列,管道这几种,都是操作系统提供的。选择一种自己能理解的方式就行了,代码都贴给你
http://blog.it2048.cn/article-php-thread/ PS:600 万行这么少的数据,几句代码就能搞定,用啥多线程。 就算用了多线程速度也提升不了多少,MySQL 的硬盘 IO 会是瓶颈。比如每秒 40M,你写入数据的极限也差不多是 40M/s。 |
29
wizardoz 2018-08-07 10:30:33 +08:00
为啥要用 php 处理?不是放进数据库用 SQL 处理最快吗?
|
30
allgy 2018-08-07 10:54:46 +08:00
@jsjscool @alwayshere php 的线程就是个废物不建议使用,大数据量用存储过程就行
|
31
slince 2018-08-07 12:33:32 +08:00
这种问题应该要你们的 dba,为啥要程序员自己写脚本去解决
|
32
batter 2018-08-07 14:30:58 +08:00
说 limit 的,你是来搞笑的么,,,,,对于超大数据来说,limit 效率非常的低,既然按照 id 处理,按照 id>$id 应该会好点吧
|
33
abccccabc 2018-08-07 14:55:33 +08:00
楼主,你还没有执行吗?队列呀,14 楼,23 楼都说了。
|