Cet article vous donnera une introduction détaillée à la persistance des connexions à une base de données en PHP. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde.
L'optimisation des bases de données est notre priorité absolue en matière de développement Web et, dans de nombreux cas, nous programmons en fait pour des bases de données. Bien entendu, toutes les opérations et comportements des utilisateurs sont enregistrés sous forme de données.
Parmi ceux-ci, y a-t-il quelque chose qui peut être optimisé dans le processus de création de connexion à la base de données ? La réponse est bien sûr oui. Les langages tels que Java ont des paramètres de pool de connexions, mais PHP n'a pas de pool de connexions dans le développement ordinaire. La technologie de pool de connexions est souvent utilisée lorsque le multithreading est impliqué, donc PHP. Une nouvelle connexion sera créée à chaque exécution, alors comment optimiser la connexion de données dans ce cas ?
Examinons d'abord la définition de la persistance de la connexion à la base de données.
Une connexion persistante à la base de données est une connexion qui n'est pas fermée une fois l'exécution du script terminée. Lorsqu'une demande de connexion persistante est reçue. PHP vérifiera s'il existe déjà une connexion persistante identique (qui a été ouverte précédemment).
Si elle existe, cette connexion sera utilisée directement ; si elle n'existe pas, une nouvelle connexion sera établie. La connexion dite « même » fait référence à une connexion au même hôte utilisant le même nom d'utilisateur et le même mot de passe.
Les lecteurs qui ne comprennent pas pleinement le travail d'un serveur Web et la charge distribuée peuvent mal comprendre le rôle des connexions persistantes. En particulier, les connexions persistantes ne permettent pas d'établir une « session utilisateur » sur la même connexion, ni d'établir efficacement une transaction. En fait, à proprement parler, les connexions persistantes n’offrent aucune fonctionnalité particulière que les connexions non persistantes ne peuvent pas offrir.
Il s'agit de la persistance de connexion en PHP, mais cela souligne également que les connexions persistantes n'offrent aucune fonctionnalité spéciale que les connexions non persistantes ne peuvent pas fournir. C'est très déroutant. Ne dit-on pas que cette solution peut améliorer les performances ?
Oui, à en juger par les fonctions spéciales soulignées dans la définition ci-dessus, les connexions persistantes n'apportent pas de fonctions nouvelles ou plus avancées, mais leur plus grande utilité est d'améliorer l'efficacité, et cela signifie que les performances s'amélioreront.
Lorsque la surcharge liée à la création d'une connexion du serveur Web au serveur SQL est élevée (par exemple, cela prend beaucoup de temps et consomme beaucoup de mémoire temporaire), la connexion persistante sera plus efficace.
C'est-à-dire que lorsque le coût de connexion est élevé, le coût de création d'une connexion à une base de données sera plus important, et bien sûr le temps sera plus long. Après avoir utilisé des connexions persistantes, chaque processus enfant n'effectue une opération de connexion qu'une seule fois dans son cycle de vie, au lieu de faire une demande de connexion au serveur SQL à chaque fois qu'il traite une page. Cela signifie que chaque processus enfant établira sa propre connexion persistante indépendante au serveur.
Par exemple, si 20 processus enfants différents exécutent un script qui établit une connexion persistante au serveur SQL, alors 20 connexions persistantes différentes sont réellement établies au serveur SQL, une pour chaque processus.
Sans plus tard, comparons directement via le code. Tout d’abord, nous définissons une fonction statistique pour renvoyer l’heure actuelle en millisecondes. De plus, nous devons également préparer les paramètres de connexion de données.
function getmicrotime() { list($usec, $sec) = explode(" ", microtime()); return ((float) $usec + (float) $sec); } $db = [ 'server' => 'localhost:3306', 'user' => 'root', 'password' => '', 'database' => 'blog_test', ];
Ensuite, nous utilisons d'abord MySQLi ordinaire pour tester.
$startTime = getmicrotime(); for ($i = 0; $i < 1000; $i++) { $mysqli = new mysqli($db["server"], $db["user"], $db["password"], $db["database"]); //持久连接 $mysqli->close(); } echo bcsub(getmicrotime(), $startTime, 10), PHP_EOL; // 6.5814000000
Dans le processus de création d'une connexion à la base de données à travers 1000 cycles, nous avons passé plus de 6 secondes. Ensuite, nous utilisons des connexions persistantes pour créer ces 1 000 connexions à la base de données. Ajoutez simplement un p: avant le paramètre $host de mysqli.
$startTime = getmicrotime(); for ($i = 0; $i < 1000; $i++) { $mysqli = new mysqli('p:' . $db["server"], $db["user"], $db["password"], $db["database"]); //持久连接 $mysqli->close(); } echo bcsub(getmicrotime(), $startTime, 10), PHP_EOL; // 0.0965000000
Du point de vue de la connexion mysqli, l'amélioration de l'efficacité est très évidente. Bien entendu, la connexion à la base de données PDO offre également la propriété d'établir une connexion persistante.
$startTime = getmicrotime(); for ($i = 0; $i < 1000; $i++) { $pdo = new PDO("mysql:dbname={$db['database']};host={$db['server']}", $db['user'], $db['password']); } echo bcsub(getmicrotime(), $startTime, 10), PHP_EOL; // 6.6171000000 $startTime = getmicrotime(); for ($i = 0; $i < 1000; $i++) { $pdo = new PDO("mysql:dbname={$db['database']};host={$db['server']}", $db['user'], $db['password'], [PDO::ATTR_PERSISTENT => true]); //持久连接 } echo bcsub(getmicrotime(), $startTime, 10), PHP_EOL; // 0.0398000000
Lors de la connexion en mode PDO, vous devez donner un paramètre PDO::ATTR_PERSISTENT et le définir sur true. De cette manière, la connexion établie par PDO devient également une connexion persistante.
Étant donné que la connexion persistante de la base de données est si puissante, pourquoi ne pas utiliser par défaut ce formulaire de connexion persistante, et devons-nous ajouter manuellement des paramètres pour y parvenir ? Les développeurs PHP ont certainement encore des inquiétudes.
Si le nombre de processus enfants avec des connexions persistantes dépasse la limite définie pour le nombre de connexions à la base de données, le système provoquera des problèmes. Si la base de données est limitée à 16 connexions simultanées et que, dans le cas d'une session occupée, 17 threads tentent de se connecter, un thread ne parviendra pas à se connecter. Si à ce moment, une erreur survient dans le script empêchant la fermeture de la connexion (comme une boucle infinie), les 16 connexions à la base de données seront rapidement affectées.
Dans le même temps, les verrous de table et les transactions nécessitent également une attention particulière.
Lors de l'utilisation d'un verrou de table dans une connexion persistante, si le script ne peut pas libérer le verrou de table pour une raison quelconque, les scripts suivants utilisant la même connexion seront définitivement bloqués, nécessitant le redémarrage du service httpd ou de la base de données.
在使用事务处理时,如果脚本在事务阻塞产生前结束,则该阻塞也会影响到使用相同连接的下一个脚本
所以,在使用表锁及事务的情况下,最好还是不要使用持久化的数据库连接。不过好在持久连接和普通连接是可以在任何时候互换的,我们定义两种连接形式,在不同的情况下使用不同的连接即可解决类似的问题。
事物总有两面性,持久连接一方面带来了效率的提升,但另一方面也可能带来一些业务逻辑上的问题,而且这种问题如果在不了解持久连接的机制的情况下会非常难排查。因此,在日常开发中我们一定要在了解相关功能特性的情况下再选择适合的方式来完成所需要的功能开发。
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/php/202004/source/PHP%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%8C%81%E4%B9%85%E5%8C%96.php
推荐学习:php视频教程
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!