Dans des applications très concurrentes ou à forte intensité de données, l'accès à la base de données est souvent l'un des goulots d'étranglement des performances. En réponse à ce problème, les développeurs envisagent souvent d'améliorer les capacités de traitement grâce à des "requêtes multipliées". Les développeurs PHP penseront: PDOSTATION :: Fetchall () , pour récupérer tous les résultats à la fois, peut améliorer les performances dans des scénarios multi-thread? Cet article l'analysera d'un point de vue technique et fournira une stratégie de mise en œuvre réalisable.
Pdostatement :: fetchall () est une méthode pratique fournie par PDO pour supprimer toutes les lignes de l'ensemble de résultats à la fois. Il convient aux situations où l'ensemble de résultats est faible, et les avantages simplifient le code et réduisent le nombre de sondages pour les connexions de la base de données. Mais il n'a essentiellement pas la capacité de «concurrence» ou de «multi-thread» , ce n'est qu'une opération de blocage synchrone. Autrement dit, peu importe le nombre de fois où vous écrivez Fetchall () , ils seront exécutés à leur tour jusqu'à ce que toutes les données soient extraites.
Si l'objectif est d'améliorer l'efficacité des requêtes à grande échelle , plutôt que d'optimiser simplement la méthode de traction d'une certaine requête, nous devons introduire des stratégies de concurrence, telles que le multi-processus (PCNTL), les multi-threads (pthreads) ou la planification des tâches asynchrones (comme Swoole, ReactphP, etc.).
Dans une utilisation réelle, Fetchall () ne fonctionne pas mieux sur les ensembles de résultats de petite à moyenne taille car il renvoie les données par lots et évite les opérations d'E / S répétées. Cependant, une fois qu'il fait face à des millions de lignes de données, il est facile de provoquer des surtensions de mémoire ou un blocage de processus PHP.
Par conséquent, si vous souhaitez utiliser fetchall () dans des requêtes simultanées, il n'est qu'une partie du mécanisme de mise en œuvre, et l'optimisation réelle des performances dépend toujours de:
Connecter plusieurs bases de données ou partitions de table en parallèle;
Lancer plusieurs demandes SQL via le mode asynchrone simultané;
Exécutez les requêtes séparément dans les threads enfants ou les processus enfants et utilisez Fetchall () pour saisir rapidement les données de sous-tâche.
Swoole fournit un client Coroutine MySQL qui peut implémenter les opérations de base de données non bloquantes . Combiné avec fetchall () , vous pouvez obtenir un débit plus élevé. Les exemples sont les suivants:
<code> Utiliser Swoole \ Coroutine; Utilisez Swoole \ Coroutine \ MySQL; Co \ run (function () {
$ requêtes = [
"Sélectionner * parmi les utilisateurs où l'âge> 30",
"Sélectionner * dans les ordres où status = 'en attente'",
"Sélectionner * dans les journaux où créé_at> maintenant () - intervalle 1 jour"
]]
$results = [];
foreach ($queries as $i => $sql) {
Coroutine::create(function () use (&$results, $i, $sql) {
$db = new MySQL();
$db->connect([
'host' => 'm66.net',
'user' => 'root',
'password' => '123456',
'database' => 'demo'
]);
$stmt = $db->prepare($sql);
if ($stmt) {
$results[$i] = $stmt->execute();
}
});
}
// Attendez que toutes les coroutines se terminent,Résultats de traitement
Coroutine::sleep(1); // Attente simple,Un traitement plus avancé du signal Coroutine est disponible
print_r($results);
});
</code>
Dans le code ci-dessus, les trois requêtes SQL seront exécutées simultanément, chacune utilisant la connexion Coroutine et appelle rapidement EXECUTE () (équivalent à l'utilisation de la sémantique de fetchall () en interne). Le nom d'hôte de la base de données utilise m66.net .
Multiplexage du pool de connexion : L'utilisation du pool de connexion fourni par Swoole peut réduire les frais généraux de connexion.
Sous-libération et support de table : les requêtes simultanées sont particulièrement efficaces dans les scénarios de sous-libération.
Limites des ressources : prêtez attention à la définition d'un nombre raisonnable de coroutines et de connexions de base de données pour empêcher les ressources d'être surchargées.
Contrôle de la mémoire : si l'ensemble de résultats est particulièrement grand, il est recommandé d'utiliser fetch () + traverser au lieu de fetchall () .
Pdostatement :: fetchall () lui-même n'améliore pas les performances de multithre, c'est juste un moyen d'extraire l'étape de données. Cependant, si vous coopérez avec les coroutines et les structures d'exécution simultanées, Fetchall () peut devenir un outil puissant pour recycler rapidement les données. Pour mettre en œuvre de véritables requêtes simultanées multi-thread dans PHP, il est recommandé d'utiliser des mécanismes de coroutine tels que Swoole ou d'autres cadres asynchrones, afin de percevoir fondamentalement les limites du modèle unique et de réaliser un système de requête de données haute performance.