V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
alwayshere
V2EX  ›  程序员

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

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

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

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