Créer un traitement parallèle PHP à partir de la demande de principe getResult
P粉649990163
P粉649990163 2023-09-14 19:30:46
0
1
488

Je souhaite faire une sorte de multithreading dans un environnement PHP8/Symfony6 et cela fonctionne comme ceci :

Je fais une demande principale qui dessert environ un million de lignes

Je souhaite créer plusieurs processus parallèles pour traiter les lignes en même temps. Ma requête se fait via getResult() qui sert l'objet doctrine. Existe-t-il un moyen de créer un thread avec un tableau d'objets comme paramètre. Puis créer des fils de discussion chaque fois que ma « file d'attente » est remplie de données ?

J'ai trouvé quelques informations sur "pthreads" ou "popen" mais je ne sais pas si c'est toujours d'actualité car le sujet date un peu

P粉649990163
P粉649990163

répondre à tous(1)
P粉211273535

Dans ce cas, l'une des choses que Doctrine fait est d'hydrater une classe avec le contenu des données, de sorte que les millions d'enregistrements soient convertis en classes et les conservent en mémoire, donc quelques suggestions : p>

  1. Évitez d'utiliser getResult dans les requêtes volumineuses. Au lieu de cela, si vous souhaitez faire quelque chose avec cet objet, essayez de paginer et d'effacer le gestionnaire d'entités, comme :
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. Utilisez while pour interroger directement :
<?php

$sql = <<<SQL
SELECT
    *
FROM user u
SQL;

$statement = $connection->prepare($sql);

$statement->execute();

while ($user = $statement->fetch()) {
    // print_r($user);
}

Vous pouvez également utiliser une boucle fetchAll 方法一次获取所有用户,但请注意,如果您的查询返回太多用户,则可能会耗尽内存。使用上面的 while, vous ne récupérez qu'un seul utilisateur en mémoire à la fois, les performances de la mémoire sont donc meilleures.

<?php

// ...

// all users are in memory here
$users = $connection->fetchAll($sql);

foreach ($users as $user) {
    // print_r($user);
}

Comme quelqu'un l'a commenté, vous pouvez utiliser

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!