Je viens de faire une nouvelle installation de XAMPP. Lors de la première ouverture de PHPMyAdmin, j'ai remarqué que c'était extrêmement lent. Cela n'avait aucun sens que sur localhost, l'ouverture de chaque page devrait prendre près de 5 secondes. J'ai fait un petit test pour décourager PHPMyAdmin:
$con = new PDO("mysql:host=localhost;dbname=mysql", "root", "");
$statement = $con->query('SELECT host,user,password FROM user;');
$users = $statement->fetchAll(PDO::FETCH_ASSOC);
Le script ci-dessus prend environ 3 secondes à exécuter (bien qu'il ait fallu près de 8 secondes pour se charger la première fois que je l'ai exécuté.)
Ensuite, pour vérifier si c'était la faute de PDO, j'ai essayé d'utiliser à la mysql_connect
place:
$con = mysql_connect("localhost", "root", "");
mysql_select_db("mysql", $con);
$result = mysql_query('SELECT host,user,password FROM user;');
Prend exactement autant de temps pour terminer.
Je pensais que c'était la faute de PHP au début, mais le code PHP et les fichiers statiques sont plus rapides que je ne peux cliquer sur Actualiser. J'ai testé PHP en exécutant ce petit script:
header("Content-Type: text/plain");
for($i = 0; $i < 5000; $i++)
{
echo sha1(rand()) . "\n";
}
5000 sha1
calculs et la page est toujours plus vivante que je ne peux rafraîchir ma fenêtre.
Ensuite, j'ai pensé que c'était la faute de MySQL. Mais encore une fois, il n'a pas fallu beaucoup de tests pour comprendre que MySQL fonctionne plus rapidement que je n'en ai besoin. En utilisant le client CLI MySQL, la requête de sélection de l'utilisateur ne prend même pas de temps mesurable - c'est fait avant même d'avoir laissé la touche de retour enfoncée.
Le problème doit être la connexion de PHP à MySQL - c'est pour autant que j'ai pu raisonner. Je peux trouver des tonnes de choses sur PHP étant lent ou MySQL lent, mais rien sur PHP + MySQL étant extrêmement lent.
Merci à tous ceux qui peuvent m'aider à résoudre ce problème!
J'utilise XAMPP 1.8.0 pour win32 ( Lien de téléchargement )
Version PHP: 5.4.4
Version MySQL: 14.14
EDIT: Après le chronométrage, il s'avère que c'est la fonction de connexion qui prend si longtemps:
$time = microtime(true);
$con = mysql_connect("localhost", "root", "");
mysql_select_db("mysql", $con);
$con_time = microtime(true);
$result = mysql_query('SELECT host,user,password FROM user;');
$sel_time = microtime(true);
printf("Connect time: %f\nQuery time: %f\n",
$con_time-$time,
$sel_time-$con_time);
Production:
Temps de connexion: 1,006148 Temps de requête: 0,000247
Qu'est-ce qui peut faire que PHP passe beaucoup de temps à se connecter à la base de données? Le client CLI, HeidiSQL et MySQL Workbench se connectent instantanément
Réponses:
Se peut-il que votre mysql essaie d'exécuter la requête rev-dns chaque fois que vous vous connectez? essayez d'ajouter à my.cnf, section mysqld: skip-nom-résoudre .
la source
Ceci est pris presque mot pour mot de ma réponse ici , mais je sais que nous fronçons les sourcils sur les réponses uniquement sur SO donc j'imagine que vous le faites aussi :-)
Si vous rencontrez ce problème et utilisez une version de Windows antérieure à Windows 7, ce n'est probablement pas la réponse à votre problème.
Pourquoi cela arrive-t-il?
La cause de ce problème est IPv4 vs IPv6.
Lorsque vous utilisez un nom d'hôte au lieu d'une adresse IP, le client MySQL exécute d'abord une
AAAA
recherche d'hôte (IPv6) pour le nom et essaie d'abord cette adresse s'il réussit à résoudre le nom en adresse IPv6. Si l'une des étapes échoue (résolution de nom ou connexion), elle reviendra à IPv4, exécutant uneA
recherche et essayant cet hôte à la place.En pratique, cela signifie que si la
localhost
recherche IPv6 réussit mais que MySQL n'est pas lié au bouclage IPv6, vous devrez attendre un cycle d'expiration de connexion avant que le repli IPv4 ne se produise et que la connexion réussisse.Ce n'était pas un problème avant Windows 7, car la
localhost
résolution était effectuée via le fichier hosts, et il était préconfiguré uniquement127.0.0.1
- il n'était pas fourni avec son homologue IPv6::1
.Depuis Windows 7, cependant, la
localhost
résolution est intégrée au résolveur DNS, pour les raisons décrites ici . Cela signifie que la recherche IPv6 va maintenant réussir - mais MySQL n'est pas lié à cette adresse IPv6, donc la connexion échouera et vous verrez le délai décrit dans cette question.C'est zonte. Dites-moi simplement comment y remédier déjà!
Vous avez quelques options. En regardant autour d'Internet, la «solution» générale semble être d'utiliser explicitement l'adresse IP au lieu du nom, mais il y a quelques raisons de ne pas le faire, toutes deux liées à la portabilité, sans doute sans importance:
Si vous déplacez votre script vers une autre machine qui ne prend en charge que IPv6, votre script ne fonctionnera plus.
Si vous déplacez votre script vers un environnement d'hébergement basé sur * nix, la chaîne magique
localhost
signifierait que le client MySQL préférerait utiliser une socket Unix si une est configurée, c'est plus efficace que la connectivité basée sur le bouclage IPIls semblent assez importants cependant?
Ils ne le sont pas. Vous devez concevoir votre application pour que ce genre de chose soit défini dans un fichier de configuration. Si vous déplacez votre script vers un autre environnement, il est probable que d'autres choses devront également être configurées.
En résumé, l'utilisation de l'adresse IP n'est pas la meilleure solution, mais elle est probablement acceptable.
Quelle est donc la meilleure solution?
La meilleure façon serait de changer l'adresse de liaison utilisée par le serveur MySQL. Cependant, ce n'est pas aussi simple qu'on pourrait le souhaiter. Contrairement à Apache, Nginx et à presque toutes les autres applications de service réseau sensées jamais créées, MySQL ne prend en charge qu'une seule adresse de liaison, il ne s'agit donc pas simplement d'en ajouter une autre. Heureusement, les systèmes d'exploitation prennent en charge un peu de magie ici, nous pouvons donc permettre à MySQL d'utiliser simultanément IPv4 et IPv6.
Vous devez exécuter MySQL 5.5.3 ou une version ultérieure, et vous devez démarrer MySQL avec l'
--bind-address=
argument de ligne de commande. Vous avez 4 documents d' options , selon ce que vous voulez faire:Celui que vous connaissez probablement, et celui que vous êtes le plus susceptible (efficace) en utilisant
0.0.0.0
. Cela se lie à toutes les adresses IPv4 disponibles sur la machine. En fait, ce n'est probablement pas la meilleure chose à faire même si vous ne vous souciez pas d'IPv6, car il souffre des mêmes risques de sécurité que::
.Une adresse IPv4 ou IPv6 explicite (par exemple
127.0.0.1
ou::1
pour le bouclage). Cela lie le serveur à cette adresse et uniquement à cette adresse.La chaîne magique
::
. Cela liera MySQL à chaque adresse de la machine, à la fois les adresses de bouclage et les interfaces physiques, en mode IPv4 et IPv6. C'est potentiellement un risque pour la sécurité, ne le faites que si vous avez besoin de MySQL pour accepter les connexions des hôtes distants.Utilisez une adresse IPv6 mappée IPv4 . Il s'agit d'un mécanisme spécial intégré à IPv6 pour une compatibilité descendante pendant la transition 4 -> 6, et il vous permet de vous lier à une adresse IPv4 spécifique et à son équivalent IPv6. Il est peu probable que cela vous soit utile pour autre chose que l'adresse de "double bouclage"
::ffff:127.0.0.1
. Il s'agit probablement de la meilleure solution pour la plupart des gens, ne se liant qu'au bouclage mais autorisant les connexions IPv4 et IPv6.Dois-je modifier le fichier hosts?
Non . Ne modifiez pas le fichier hosts. Le résolveur DNS sait quoi faire
localhost
, le redéfinir n'aura au mieux aucun effet, et au pire confondra l'enfer du résolveur.Et alors
--skip-name-resolve
?Cela peut également résoudre le problème, pour une raison connexe mais légèrement différente.
Sans cette option de configuration, MySQL tentera de résoudre toutes les adresses IP de connexion client en un nom d'hôte via une
PTR
requête DNS. Si votre serveur MySQL est déjà activé pour utiliser IPv6 mais que les connexions prennent encore du temps, cela peut être dû au fait que l'enregistrement DNS inversé (PTR
) n'est pas correctement configuré.La désactivation de la résolution de noms résoudra ce problème, mais elle a d'autres ramifications, notamment que toutes les autorisations d'accès configurées pour utiliser un nom DNS dans la
Host
condition échouent désormais.Si vous comptez le faire, vous devrez configurer toutes vos autorisations pour utiliser des adresses IP au lieu de noms.
la source
::1
. Malheureusement, a::ffff:127.0.0.1
continué de me donner un délai d'une seconde (indépendamment de l'utilisationskip-name-resolve
ou non), des idées pourquoi? (sous Windows 8.1)Habituellement, lorsque IPv6 est activé dans les connexions serveur à MySQL, l'utilisation
localhost
est extrêmement lente.Changer l'adresse du serveur mysql dans le script pour
127.0.0.1
résoudre le problème.la source
localhost
résolveur DNS pour la raison que @DaveRandom lié à: serverfault.com/questions/4689/…localhost
. J'ai eu le même problème de délai pour une adresse de serveur sur le formulairexx.xxxx.xxxxx.xxxxx.com
. Une fois que j'ai changé le nom du serveur en son adresse IP, le problème a disparu.Eh bien, la raison en est assez évidente. PHP est vraiment bon à certains égards, mais pas à traduire directement «localhost» en «127.0.0.1». Vous devez essayer cela, cela réduira vraiment le temps de chargement global de votre page Web, car il empêche PHP de vérifier votre fichier HOSTS et ce qu'il ne fait pas pour obtenir la véritable adresse IP derrière «localhost»
la source
L'ajout de cette ligne à votre fichier d'hôtes a résolu le problème pour moi
La réponse détaillée peut être trouvée dans ce fil: /programming/13584360/php-with-mysql-is-slow
la source
Vous pouvez également éliminer le ralentissement des requêtes en apportant un petit ajustement à votre variable de connexion db (qui, espérons-le, se trouve dans un fichier distinct de vos scripts pour la portabilité). Modifiez la valeur d'hôte en "127.0.0.1" au lieu de "localhost". Cela contourne la longue recherche DNS pour localhost.
J'espère que cela t'aides!
la source