suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Erstellen Sie eine PHP-Parallelverarbeitung aus der getResult-Prinzipanforderung

Ich möchte eine Art Multithreading in einer PHP8/Symfony6-Umgebung durchführen und es funktioniert so:

Ich stelle eine Hauptanfrage, die etwa eine Million Zeilen bedient

Ich möchte mehrere parallele Prozesse erstellen, um die Zeilen gleichzeitig zu verarbeiten. Meine Anfrage erfolgt über getResult(), das das Doctrine-Objekt bedient. Gibt es eine Möglichkeit, einen Thread mit einem Array von Objekten als Parameter zu erstellen? Dann Threads erstellen, wann immer meine „Warteschlange“ mit Daten gefüllt ist?

Ich habe einige Informationen zu „pthreads“ oder „popen“ gefunden, bin mir aber nicht sicher, ob sie noch relevant sind, da das Thema schon etwas alt ist

P粉649990163P粉649990163438 Tage vor559

Antworte allen(1)Ich werde antworten

  • 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);
    }
    

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

    Antwort
    0
  • StornierenAntwort