• 请不要在回答技术问题时复制粘贴 AI 生成的内容
alwayshere
V2EX  ›  程序员

PHP 脚本要对 600 万行的 mysql 进行一次批处理操作,怎样才能用多个进程达到最快执行?

  •  
  •   alwayshere · Aug 6, 2018 · 6144 views
    This topic created in 3019 days ago, the information mentioned may be changed or developed.

    要扫描一次全表,php 对每一行都要批处理一次,如果单个 php 进程把 600 万行载入内存扫描一次全表处理实在太慢,想用多个 php 进程来扫描表:

    1. 想用多个 php 进程从 MySQL 中随机取出一些行出来,因为 primary id 不连续,但用 MySQL 的 ORDER BY RAND()慢的令人发指

    2. 想快一点也只能用两个 php 进程,一个 ORDER BY id ASC 顺序执行,一个 ORDERY BY id DESC 倒序执行,但两个进程还是太慢

    估计表述得不太明白,反正就是怎样能将 mysql 快速截取成一段一段的行,让多个 php 进程去执行?

    33 replies  •  2018-08-07 14:55:33 +08:00
    Sornets
    Sornets
    Aug 6, 2018
    1
    一个思路:
    记录 id 取余,比如十个进程,就对 10 取余,根据余数查找对应 id,proc_id = rec_id % 10,
    z550665887
    z550665887
    Aug 6, 2018
    2
    limit ?
    582033
    582033
    Aug 6, 2018
    3
    分页
    Rekkles
    Rekkles
    Aug 6, 2018
    4
    PHP 哪有什么多进程 pthread 性能不会有太大的提高 这种东西如果打算用 PHP 做,mysql 和内存 能扛就能做,一次取 1k 条数据(内存够就多取点),处理 ,update,循环
    lihongjie0209
    lihongjie0209
    Aug 6, 2018
    5
    生产者消费者喽
    widdy
    widdy
    Aug 6, 2018❤️2
    6
    有这扯淡时间,一个脚本 600w 行早跑完了,为啥不一次取个 1w 条。
    nsxuan
    nsxuan
    Aug 6, 2018
    7
    关键是要开启事务
    colincat
    colincat
    Aug 6, 2018
    8
    @widdy 说的没毛病
    newtype0092
    newtype0092
    Aug 6, 2018
    9
    @widdy 那就来讨论下 6 亿条怎么做嘛,让这个淡扯的有点意义~
    tanszhe
    tanszhe
    Aug 6, 2018
    10
    这种简单到爆的问题 就不要来问了
    mumbler
    mumbler
    Aug 6, 2018
    11
    order by id limit 1,10000
    order by id limit 10001,10000
    order by id limit 20001,10000
    order by id limit 30001,10000
    这样就可以一万一万读了,和分页一样
    widdy
    widdy
    Aug 6, 2018
    12
    @newtype0092 , 真这么大,时间来最清晰,php xxoo.php 2017-01 , php xxoo.php 2017-02 ...
    ps1aniuge
    ps1aniuge
    Aug 6, 2018
    13
    一个进程不行,就多个进程。多个进程不行就 n 机子分布。
    这里面要有一个队列,分发任务或表 id。根据实际情况,一次分发一百,一千,一万。
    vovov
    vovov
    Aug 6, 2018 via Android
    14
    用队列,随便多少条都可以
    GGGG430
    GGGG430
    Aug 6, 2018 via iPhone
    15
    pcntl,我上周才刚用过,你把行数除以进程数,然后把各个起始 id 传给各个子进程,快的一比
    yuanfnadi
    yuanfnadi
    Aug 6, 2018
    16
    select * from xxx where id > 0 limit 1000
    然后取最后一个 ID 为 1022
    select * from xxx where id > 1022 limit 1000
    想开几个线程都可以。
    GGGG430
    GGGG430
    Aug 6, 2018 via iPhone
    17
    不要排序,各个进程处理各自起始 id 部门数据,然后各个进程都每次取 100 条数据作为一个事物提交,但注意 mysql 连接数和执行脚本机器的负载
    dobelee
    dobelee
    Aug 6, 2018 via Android
    18
    600w。。随便跑跑就行,等你写好算法逻辑,10 遍都跑完了。
    jswh
    jswh
    Aug 6, 2018
    19
    记得别用对象,用数组就行
    InternetExplorer
    InternetExplorer
    Aug 6, 2018
    20
    能不能直接用 sql 处理?
    xmadi
    xmadi
    Aug 6, 2018 via iPhone
    21
    用 limit 效率很低 可以直接先人工查询最大的 id 和最小的 id 然后以十万个 id 间隔分组 很粗糙肯定不均匀但是没有影响 开进程池 每个进程用 where 筛选分组数据进行处理
    bugsnail
    bugsnail
    Aug 6, 2018 via iPhone
    22
    @mumbler https://oyifan.com/2016/03/23/offsetSlow/

    了解一下,limit 是会越来越慢的
    singer
    singer
    PRO
    Aug 6, 2018 via iPhone
    23
    id 放到 redis 的 list,然后多进程拉起来就好了个
    xschaoya
    xschaoya
    Aug 6, 2018
    24
    最简单的多进程资源分配啊,简单粗暴的就是主键分段开多进程。高级点的可以用消息队里(生产者消费者类模型)
    GreatHumorist
    GreatHumorist
    Aug 6, 2018 via iPhone
    25
    还是想想直接用 sql 吧,php 弄很麻烦,上周末弄过一个三百万行的匹配,php 遍历到十万左右就很慢了。最后直接用 sql,贼快,加起来不超过 10 分钟
    yangqi
    yangqi
    Aug 6, 2018
    26
    多复杂的处理不能在 mysql 里面完成?
    beastk
    beastk
    Aug 6, 2018 via iPhone
    27
    要不就用 php 执行个 go 或者 python,分分钟给你跑完
    jsjscool
    jsjscool
    Aug 6, 2018
    28
    使用进程间通信也是几句代码的事情。和语言无关,通信的方式无非就是信号量,消息队列,管道这几种,都是操作系统提供的。选择一种自己能理解的方式就行了,代码都贴给你
    http://blog.it2048.cn/article-php-thread/

    PS:600 万行这么少的数据,几句代码就能搞定,用啥多线程。 就算用了多线程速度也提升不了多少,MySQL 的硬盘 IO 会是瓶颈。比如每秒 40M,你写入数据的极限也差不多是 40M/s。
    wizardoz
    wizardoz
    Aug 7, 2018
    29
    为啥要用 php 处理?不是放进数据库用 SQL 处理最快吗?
    allgy
    allgy
    Aug 7, 2018
    30
    @jsjscool @alwayshere php 的线程就是个废物不建议使用,大数据量用存储过程就行
    slince
    slince
    Aug 7, 2018
    31
    这种问题应该要你们的 dba,为啥要程序员自己写脚本去解决
    batter
    batter
    Aug 7, 2018
    32
    说 limit 的,你是来搞笑的么,,,,,对于超大数据来说,limit 效率非常的低,既然按照 id 处理,按照 id>$id 应该会好点吧
    abccccabc
    abccccabc
    Aug 7, 2018
    33
    楼主,你还没有执行吗?队列呀,14 楼,23 楼都说了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   942 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 75ms · UTC 22:30 · PVG 06:30 · LAX 14:30 · JFK 17:30
    ♥ Do have faith in what you're doing.