Les développeurs rencontrent souvent des problèmes d'optimisation des performances lors de l'utilisation de l'extension MySQLI de PHP pour les opérations de base de données. Surtout dans les scénarios de fonctionnement à haute concurrence et à haute fréquence, il devient crucial de choisir la bonne fonction et sa fréquence d'appel. Cet article se concentrera sur la fonction mysqli_stmt :: att_get pour explorer s'il convient aux appels fréquents dans les opérations à haute fréquence.
mysqli_stmt :: att_get est une fonction dans l'extension mysqli pour obtenir un attribut d'instruction préparé. Le prototype est le suivant:
mixed mysqli_stmt::attr_get(int $attribute)
Il accepte une constante d'attribut en tant que paramètre, tel que mysqli_stmt_attr_update_max_length et renvoie la valeur actuelle de l'attribut.
Le scénario d'utilisation de cette fonction est principalement utilisé pour vérifier ou configurer le comportement de l'instruction avant que l'instruction de requête ne soit exécutée. Par exemple, lorsque vous devez obtenir la longueur maximale du champ pour allouer suffisamment de mémoire à l'ensemble de résultats, vous pouvez utiliser:
$stmt = $mysqli->prepare("SELECT name FROM users");
$stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
Dans ce scénario, ATTR_GET est un outil pratique pour obtenir certaines propriétés internes de l'objet instruction actuel.
L'appel de mysqli_stmt :: att_get lui-même n'est pas coûteux, car il obtient simplement une valeur d'attribut simple et ne déclenche pas la logique complexe ou la communication de base de données. Mais la clé du problème est: dans les opérations à haute fréquence, ces appels de fonction ont-ils un effet cumulatif?
PHP est une langue interprétée, et chaque appel de fonction a un certain coût de création de contexte. L'appel fréquent à ATTR_GET à l'intérieur de la concurrence ou des boucles élevées ne provoquera pas des goulots d'étranglement de performances, mais introduira également les frais généraux d'appel de fonction inutile.
Par exemple, la structure de code suivante est évidemment inefficace dans les boucles à haute fréquence:
for ($i = 0; $i < 100000; $i++) {
$stmt = $mysqli->prepare("SELECT name FROM users WHERE id = ?");
$stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
// ...
}
Dans ce scénario, l'appel à Attr_get devient redondant, surtout lorsque vous ne comptez pas sur la valeur qu'il renvoie pour un jugement logique.
Bien que Astr_get n'accède pas directement à la base de données, la création fréquente d'instructions de prétraitement est elle-même un coût. La plupart du temps, ce que vous devriez vraiment optimiser, c'est la répétition de la préparation des déclarations ( prépare () ), et non att_get lui-même.
Dans les opérations à haute fréquence, si vous appelez ATTR_GET plusieurs fois pour obtenir la même valeur d'attribut et que la valeur ne change pas, vous pouvez complètement mettre en cache le résultat.
$max_length_attr = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
// Utiliser directement dans les opérations suivantes $max_length_attr,Au lieu de l'appeler à plusieurs reprises attr_get
Cette approche est logiquement sûre et plus efficace.
La fonction MySQLI_STMT :: Attr_get elle-même est légère, mais dans les opérations à haute fréquence, il n'est pas la meilleure pratique de l'appeler fréquemment, en particulier dans deux cas:
La valeur d'attribut ne changera pas : le résultat du cache doit être pris en compte;
Appelé dans une boucle : il doit être éloigné de la boucle, ou la structure du programme doit être ajustée pour éviter une acquisition répétée;
Lors de l'optimisation des performances du fonctionnement de la base de données PHP, une plus grande attention doit être accordée à la gestion de la connexion de la base de données, au multiplexage des instructions de prétraitement, à la latence du réseau et aux goulots d'étranglement d'E / S. La micro-optimisation des appels de fonction est la cerise sur le gâteau, mais elle ne doit pas être éclipsée.
Avant l'optimisation:
for ($i = 0; $i < 10000; $i++) {
$stmt = $mysqli->prepare("SELECT name FROM users WHERE id = ?");
$stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH);
}
Après l'optimisation: