首页  >  问答  >  正文

从 getResult 原则请求创建 PHP 并行处理

我想在 PHP8/Symfony6 环境中执行某种多线程,其工作方式如下:

我正在提出一个原则请求,该请求服务于大约一百万行

我想创建多个并行进程来同时处理这些行。 我的请求是通过 getResult() 发出的,它服务于学说对象。 有没有一种方法可以创建带有对象数组作为参数的线程。然后只要我的“队列”充满数据就创建线程?

我找到了一些有关“pthreads”或“popen”的信息,但我不确定它是否仍然相关,因为主题有点旧

P粉649990163P粉649990163422 天前544

全部回复(1)我来回复

  • P粉211273535

    P粉2112735352023-09-15 10:29:17

    在这种情况下,Doctrine 所做的事情之一就是用数据内容水合一个类,因此所有数百万条记录都会转换为类并将它们保存在内存中,因此有几个建议:

    1. 避免在大型查询中使用 getResult。相反,如果您要执行此对象的某些操作,请尝试分页并清除实体管理器,例如:
    public function paginate(int $start = 0, int $offset = 10): Doctrine\ORM\Tools\Pagination\Paginator
    {
        $qb = $this->createQueryBuilder('student');
        $qb
           ->where($qb->expr()->isNull('student.schoolRef'))
           ->setFirstResult($start)
           ->setMaxResults($offset);
        return new Paginator($qb, true);
    }
    
    src/Service.php
    
    $start = 0;
    $offset = 100;
    do {
        $i = 0;
        $students = $this->studentRepository->paginate($start, $offset);
        foreach($students as $student) {
        //do stuff
          ++$i;
        }
        $this->entityManager->flush();
        $this->entityManager->clear();
    } while ($i == $offset);
    1. 使用 while 直接查询:
    <?php
    
    $sql = <<<SQL
    SELECT
        *
    FROM user u
    SQL;
    
    $statement = $connection->prepare($sql);
    
    $statement->execute();
    
    while ($user = $statement->fetch()) {
        // print_r($user);
    }

    您还可以使用 fetchAll 方法一次获取所有用户,但请注意,如果您的查询返回太多用户,则可能会耗尽内存。使用上面的 while 循环,您一次仅将一个用户提取到内存中,因此内存性能更好。

    <?php
    
    // ...
    
    // all users are in memory here
    $users = $connection->fetchAll($sql);
    
    foreach ($users as $user) {
        // print_r($user);
    }
    

    正如有人评论的那样,你可以使用

    回复
    0
  • 取消回复