搜尋

首頁  >  問答  >  主體

從 getResult 原則請求建立 PHP 並行處理

我想在 PHP8/Symfony6 環境中執行某種多線程,其工作方式如下:

我正在提出一個原則請求,該請求服務於大約一百萬行

我想建立多個並行進程來同時處理這些行。 我的請求是透過 getResult() 發出的,它服務於學說對象。 有沒有一種方法可以創建帶有物件數組作為參數的線程。然後只要我的“隊列”充滿數據就創建線程?

我找到了一些有關“pthreads”或“popen”的信息,但我不確定它是否仍然相關,因為主題有點舊

P粉649990163P粉649990163438 天前560

全部回覆(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
  • 取消回覆