要扫描一次全表,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 ![]() 有这扯淡时间,一个脚本 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 vovov 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 楼都说了。 |