Écrire des requêtes MySQL ultra-rapides

Les différences entre SQL bien écrit et non écrit sont vastes et, en production sur un site à forte demande, elles ont de graves répercussions sur les performances et la fiabilité du service. Dans ce guide, j'expliquerai comment écrire des requêtes rapides et quels facteurs contribuent à les ralentir..

Pourquoi MySQL?

On parle beaucoup aujourd'hui du Big Data et des nouvelles technologies. Les solutions NoSQL et en nuage sont excellentes, mais de nombreux logiciels Web populaires (tels que WordPress, phpBB, Drupal, le logiciel VBulletin Forum, etc.) fonctionnent toujours sur MySQL. Migration vers ces nouvelles solutions peut ne pas être aussi simple que d’optimiser la configuration que vous avez déjà en production. De plus, les performances de MySQL sont très bonnes, en particulier la version Percona.

Ne commettez pas l'erreur commune de disposer de plus en plus de puissance de calcul pour résoudre le problème des requêtes lentes et des charges de serveur élevées, plutôt que de vous attaquer réellement aux problèmes sous-jacents. Ajouter de la puissance CPU, des SSD ou de la RAM est une forme d’optimisation si vous voulez, mais ce n’est pas ce dont je vais parler ici. En outre, sans site optimisé, les problèmes se multiplient de manière exponentielle à mesure que vous progressez avec les gains matériels. Ce n'est donc pas une solution solide à long terme.

Être bon en SQL est toujours un outil essentiel pour un développeur Web, et comme une solution est souvent aussi simple que d’ajouter un index ou de modifier légèrement l’utilisation de la table, il est utile de savoir comment utiliser correctement son SGBDR. Dans ce cas, nous nous concentrons sur une base de données open source populaire souvent utilisée avec PHP, à savoir MySQL..

A qui s'adresse ce guide?

Développeurs Web, architectes de bases de données / administrateurs de base de données et administrateurs système familiarisés avec MySQL. Si vous n'êtes pas familier avec MySQL en tant que débutant, alors ce guide n'aura probablement pas beaucoup de sens, mais je vais essayer de le garder le plus informatif possible pour les nouveaux arrivants à MySQL..

Sauvegardez d'abord

Je recommande d'essayer les étapes fournies sur votre propre base de données MySQL (sauvegarder tout d'abord bien sûr!). Si vous n'avez aucune base de données sur laquelle travailler, des exemples de création de schémas de base de données sont fournis, le cas échéant..

Sauvegarder MySQL est facile avec le mysqldump utilitaire de ligne de commande:

bash $ mysqldump maTable> maTable-sauvegarde.sql

Vous pouvez en apprendre plus sur mysqldump.

Ce qui rend une requête lente?

En résumé et sans ordre d'importance, les éléments suivants jouent tous un rôle important dans les performances des requêtes et des serveurs:

  • index de table
  • clause (et l’utilisation des fonctions internes de MySQL telles que SI et RENDEZ-VOUS AMOUREUX par exemple)
  • tri avec Commandé par
  • fréquence des demandes simultanées
  • type de moteur de stockage (InnoDB, MyISAM, Memory, Blackhole)
  • ne pas utiliser l'édition Percona
  • variables de configuration du serveur (réglage de my.cnf / my.ini)
  • grands ensembles de résultats (> 1 000 lignes)
  • connexions non persistantes
  • partage de partition / configuration de cluster
  • mauvaise conception de la table

Nous aborderons tous ces domaines dans ce guide. De plus, si vous ne l'utilisez pas déjà, installez Percona, un outil de remplacement immédiat pour MySQL, qui apportera une amélioration considérable des performances. Pour voir un point de repère de Percona par rapport à MySQL, regardez cette comparaison.

Que sont les index?

MySQL utilise les index pour trouver rapidement des lignes avec des valeurs de colonne spécifiques, par exemple dans . Sans index, MySQL doit commencer par la première ligne, puis parcourir l'intégralité de la table pour rechercher les lignes appropriées. Plus la table est grande, plus cela coûte cher.

Si la table a un index pour les colonnes en question, MySQL peut rapidement déterminer la position à rechercher dans le milieu du fichier de données sans avoir à regarder toutes les données. C'est beaucoup plus rapide que de lire chaque ligne séquentiellement.

Connexions non persistantes?

Lorsque votre langage de script se connecte à la base de données, si vous avez configuré des connexions persistantes, il sera alors en mesure de réutiliser une connexion existante sans avoir à en créer une nouvelle. C'est optimal pour une utilisation en production et doit être activé.

Les utilisateurs de PHP peuvent en savoir plus dans le manuel PHP.

Réduire la fréquence des demandes simultanées

Le moyen le plus rapide et le plus efficace que j'ai trouvé pour résoudre ce problème consiste à utiliser un magasin de paires clé-valeur tel que Memcached ou Redis.

Avec Memcache vous pouvez simplement mettre en cache le contenu de votre requête avec les éléments suivants, par exemple:

"php connect ('localhost', 11211); $ cacheResult = $ cache-> get ('nom de clé'); if ($ cacheResult) //… pas besoin d'interroger $ result = $ cacheResult; else // ... lancez votre requête $ mysqli = mysqli ('p: localhost', 'nom d'utilisateur', 'mot de passe', 'table'); // prepend p: to nom_hôte pour la persistance $ sql = 'SELECT * FROM messages LEFT JOIN userInfo avec (UID) WHERE posts.post_type =' post '|| posts.post_type = 'article' ORDER BY colonne LIMIT 50 '; $ result = $ mysqli-> query ($ sql); $ memc-> set ('nom-clé', $ result-> fetch_array (), MEMCACHE_COMPRESSED, 86400);

// Passez le $ cacheResult au template $ template-> assign ('posts', $ cacheResult);

?> "

Maintenant l'exemple JOINT GAUCHE La requête ne sera exécutée qu'une fois toutes les 86 400 secondes (24 heures), ce qui allégera considérablement la charge de travail du serveur MySQL et réduira le nombre de connexions simultanées..

Note: Préfini p: à l'argument de votre hôte dans MySQLi pour les connexions persistantes.

Eclatement / Clustering

Lorsque vos données deviennent volumineuses ou que la demande pour votre service augmente, la panique peut s'installer. Une solution rapide pour garantir que votre service reste en ligne peut être partagée. Mais je ne le recommande pas, car le sharding semble rendre les structures de données excessivement compliquées. Et comme expliqué très éloquemment dans cet article du blog Percona, ne partage pas.

Mauvaise conception de la table

La création de schémas de base de données n’est pas une tâche ardue lorsque vous acceptez certaines règles d’or, telles que l’utilisation des limitations et la connaissance de ce qui sera efficace. Stockage des images dans la base de données goutte Les types de données, par exemple, sont fortement déconseillés; stocker un nom de fichier dans un varchar La colonne de type de données est de loin supérieure.

Il est primordial de créer votre application en veillant à ce que la conception corresponde à l'utilisation requise. Gardez les données spécifiques séparées (par exemple, les catégories et les publications) et assurez-vous que les relations plusieurs-à-un ou un-à-plusieurs peuvent être facilement liées à des identifiants. Utilisant le CLÉ ÉTRANGÈRE fonctionnalité de MySQL est idéale pour la contingence de données en cascade entre les tables.

Lors de la construction de votre table, essayez de vous rappeler les points suivants:

  • Utilisez le minimum dont vous avez besoin pour faire le travail; être clairsemé et au point.
  • Ne vous attendez pas à ce que MySQL fasse la logique de votre entreprise ou soit programmatique, cela devrait être fait avant l'insertion par votre langage de script. Par exemple, si vous devez randomiser une liste, effectuez la randomisation d’un tableau en PHP, pas dans un COMMANDÉ PAR en MySQL.
  • Utiliser un UNIQUE type d'index pour des ensembles de données uniques et utiliser SUR MISE À JOUR DE CLÉ EN DOUBLE conserver un horodatage datetime ou unix mis à jour pour l'exemple de la dernière vérification de la ligne.
  • Utiliser un INT type de données pour les nombres entiers. Si vous ne spécifiez pas la longueur, MySQL calculera ce qui est demandé.

Les bases de l'optimisation

Pour optimiser efficacement, nous devons examiner trois ensembles de données fondamentaux concernant votre application:

  1. Analyse (enregistrement lent des requêtes, audit, analyse des requêtes et des tables)
  2. Exigences de performances (combien d'utilisateurs, quelle est la demande)
  3. Contraintes de technologie (vitesse matérielle, demander trop de MySQL)

L'analyse peut être effectuée de plusieurs manières. Premièrement, nous prendrons la voie la plus directe pour examiner sous le capot des requêtes MySQL. Le premier outil de votre boîte à outils d'optimisation est EXPLIQUE. En utilisant cela dans votre requête avant la SÉLECTIONNER vous donnera la sortie suivante:

sql mysql> EXPLAIN SELECT * FROM 'wp_posts' WHERE 'post_type' = 'post'; + ---- + ------------- + ---------- + ------ + ------------ ------ + ------------------ + --------- + ------- + ------ + ------------- + | id | select_type | table | type | possible_keys | clé | key_len | ref | rangées | Extra | + ---- + ------------- + ---------- + ------ + ------------ ------ + ------------------ + --------- + ------- + ------ + ------------- + | 1 | SIMPLE | wp_posts | ref | type_status_date | type_status_date | 82 | const | 2 | Utiliser où | + ---- + ------------- + ---------- + ------ + ------------ ------ + ------------------ + --------- + ------- + ------ + ------------- + 1 ligne dans le set (0.00 sec)

Les colonnes répertoriées contiennent chacune des informations utiles sur la requête en cours d'exécution. Les colonnes auxquelles vous devez faire très attention sont possible_keys et Supplémentaire.

possible_keys affichera les index que le moteur MySQL peut utiliser pour la requête. Parfois, vous devez forcer un index pour vous assurer que la requête est exécutée rapidement..

le Supplémentaire colonne montrera si un conditionnel ou COMMANDÉ PAR a été utilisé. Le plus important à noter est si Utilisation de Filesort apparaît. Prenons l'exemple suivant:

sql EXPLAIN SELECT main_text FROM messages WHERE user = 'monUsername' && status = '1' && (status_spam_user = 'no_spam' || (status_spam_user = 'neutre' && status_spam_system = 'neutre')) ORDER BY datum DESC LIMIT 6430, 10

Ce type de requête peut arriver sur le disque en raison du conditionnel où, ce qui se produit si nous examinons les EXPLIQUE:

sql id select_type type de table possible_keys clé key_len ref rows Extra 1 SIMPLE enregistre ref index_user, index_status index_user 32 const 7800 Utilisation de where; Utiliser le porte-fichiers

Donc, cette requête a la possibilité d’utiliser deux index et elle frappe actuellement le disque en raison de la Utiliser le porte-fichiers dans le Supplémentaire.

Quoi Utilisation de Filesort Ce que nous faisons est défini ici à partir du manuel MySQL:

«MySQL doit effectuer une passe supplémentaire pour savoir comment récupérer les lignes dans un ordre trié. Le tri s'effectue en parcourant toutes les lignes en fonction du type de jointure et en stockant la clé de tri et le pointeur sur la ligne pour toutes les lignes correspondant à la clause WHERE. Les clés sont ensuite triées et les lignes sont extraites dans un ordre trié. ”

Ce laissez-passer supplémentaire ralentira votre application et doit être évité à tout prix. Une autre cruciale Supplémentaire résultat à éviter est Utilisation temporaire, ce qui signifie que MySQL devait créer une table temporaire pour la requête. Évidemment, ceci est une utilisation hideuse de MySQL et doit être évité à tout prix, sauf si vous ne pouvez pas optimiser davantage en raison des besoins en données. Dans ce cas, la requête doit être mise en cache dans Redis ou Memcache et ne pas être exécutée par les utilisateurs..

Pour résoudre le problème avec Utilisation de Filesort nous devons nous assurer que MySQL utilise un INDICE. Il a plusieurs possible_keys choisir, mais MySQL ne peut utiliser qu'un seul index dans la requête finale. Bien que les index puissent être composites de plusieurs colonnes, l'inverse n'est pas vrai, bien que vous puissiez indiquer à l'optimiseur MySQL quels index vous avez créés..

Conseils d'index

L'optimiseur de MySQL utilisera des statistiques basées sur les tables des requêtes pour sélectionner le meilleur index pour l'étendue de la requête. Il le fait sur la base de la logique statistique de l'optimiseur intégré, bien que, avec des choix multiples, cela ne puisse pas toujours être correct sans allusion. Pour vous assurer que la clé correcte est utilisée (ou non utilisée), utilisez le INDEX DE FORCE, UTILISER L'INDEX et IGNORE INDEX mots-clés dans votre requête. Vous pouvez en savoir plus sur l'indexation d'index dans le manuel MySQL.

Pour regarder les clés de la table, utilisez la commande MONTRER INDEX.

Vous pouvez spécifier plusieurs astuces à utiliser par l'optimiseur, par exemple:

sql SELECT * FROM table1 UTILISEZ INDEX (col1_index, col2_index) WHERE col1 = 1 AND col2 = 2 AND col3 = 3;

Courir un EXPLIQUE vous montrera quel index a été utilisé dans le résultat final. Donc, pour corriger l'exemple précédent, nous allons ajouter le UTILISER L'INDEX comme tel:

sql EXPLAIN SELECT main_text FROM posts USE INDEX (index_user) WHERE user = 'monUsername' && status = '1' && (status_spam_user = 'no_spam' || (status_spam_user = 'neutre' && status_spam_system = 'neutre') ORDER BY datum LIMITE 6430, 10

Maintenant que MySQL a le état_index de la table à utiliser, la requête est corrigée.

sql id select_type type de table possible_keys clé key_len ref rows Extra 1 SIMPLE publie ref index_user, index_status index_user 32 const 7800 Utilisation de where

Aux côtés de EXPLIQUE est le DÉCRIRE mot-clé. Avec DÉCRIRE vous pouvez afficher les informations d'une table comme suit:

sql mysql> DESCRIBE City; + ------------ + ---------- + ------ + ----- + --------- + - -------------- + | Domaine | Type | Null | Clé | Par défaut | Extra | + ------------ + ---------- + ------ + ----- + --------- + - -------------- + | Id | int (11) | NON | PRI | NULL | auto_increment | | Nom | char (35) | NON | | | | | Pays | char (3) | NON | UNI | | | | District | caractère (20) | OUI MUL | | | | Population | int (11) | NON | | 0 | | +------------+----------+------+-----+---------+----------------+

Ajout d'index

Vous créez des index dans MySQL avec le CRÉER UN INDEX syntaxe. Il y a quelques saveurs d'index. TEXTE INTÉGRAL est utilisé à des fins de recherche de texte intégral, et puis il y a le UNIQUE type pour garantir que les données restent uniques.

Pour ajouter un index à votre table, utilisez la syntaxe suivante, par exemple:

sql mysql> CREATE INDEX idx_start_of_username ON 'utilisateurs' (nom d'utilisateur (10));

Cela va créer un index sur la table utilisateurs, qui utilisera les 10 premières lettres de la colonne de nom d'utilisateur, qui est un type de données varchar.

Dans ce cas, toute recherche nécessitant une trier sur le nom d'utilisateur avec la correspondance étant dans les 10 premiers caractères serait la même chose qu'une recherche de la table entière.

Indices composites

Les index ont un effet considérable sur la rapidité avec laquelle les données de la requête sont renvoyées. Le simple fait de définir une clé primaire et un index unique n’est généralement pas suffisant: les clés composites sont le véritable créneau d’ajustement dans MySQL, et le plus souvent, cela nécessite des vérifications A / B avec EXPLIQUE.

Par exemple, si nous devons référencer deux colonnes dans notre conditionnel, une clé composite serait idéale.

sql mysql> CREATE INDEX idx_composite ON utilisateurs (nom d'utilisateur, actif);

Ici, cette clé est créée sur le Nom d'utilisateur colonne de l'exemple précédent et la colonne actif, un ENUM type de données qui indique si le compte d'utilisateur est actif. Alors maintenant, lorsque vous interrogez les données pour le nom d'utilisateur est valide et le compte est actif = 1, l'ensemble de données est maintenant optimisé pour mieux gérer cette.

À quelle vitesse est votre MySQL?

Activez le profilage pour examiner de plus près vos requêtes MySQL. Cela peut être fait au moment de l'exécution via set profiling = 1, puis en exécutant votre requête et en regardant le résultat de afficher les profils.

Avec PDO, voici un extrait de code qui fait exactement cela:

"php $ db-> requête ('set profiling = 1'); $ db-> requête ('sélectionner le titre, le corps, les balises des publications'); $ rs = $ db-> requête ('afficher les profils'); $ db-> query ('set profiling = 0'); // Désactive le profilage une fois la requête exécutée.

$ records = $ rs-> fetchAll (PDO :: FETCH_ASSOC); // Obtient les résultats du profilage

$ errmsg = $ rs-> errorInfo () [2]; // Catch les erreurs ici "

Si vous n'utilisez pas PDO, vous pouvez faire la même chose avec mysqli comme tel:

"php $ db = new mysqli ($ host, $ username, $ password, $ dbname);

$ db-> query ('set profiling = 1'); $ db-> query ('select headline, body, tags from posts'); if ($ resultat = $ db-> requête (“Profils SHOW”, MYSQLI_USE_RESULT)) while ($ rang = $ résultat-> fetch_row ()) var_dump ($ rang)); $ result-> close ();

if ($ resultat = $ db-> query (“affiche le profil de la requête 1”, MYSQLI_USE_RESULT)) while ($ row = $ result-> fetch_row ()) var_dump ($ row); $ result-> close ();

$ db-> query ('set profiling = 0'); "

Cela vous renverra les données de profilage, qui incluront le temps d'exécution dans la deuxième valeur du tableau associatif:

php array (3) [0] => string (1) "1" [1] => string (10) "0.00024300" [2] => string (17) "sélection du titre, du corps, des tags dans les posts" La requête a pris 0,00024300 secondes. C'est assez rapide pour ne pas s'inquiéter. Mais lorsque les chiffres augmentent, nous devons examiner de plus près.

Par exemple, apprenez à connaître votre application. Placez un chèque pour un DÉBOGUER constante dans le pilote de base de données de la couche d'abstraction de la base de données / framework de votre application, puis vous pouvez lancer l'audit en activant un cas de profil et en affichant le résultat avec var_dump / print_r. Maintenant, vous serez en mesure de parcourir et de profiler facilement les pages de votre site Web.!

Audit complet de votre application

Pour effectuer un audit complet de vos requêtes, activez la journalisation. Certains développeurs avec lesquels j'ai travaillé craignent qu'il ne s'agisse d'un problème à double face, car l'activation de la journalisation affecte légèrement les performances. Les statistiques que vous enregistrez seront donc légèrement inférieures à la réalité. Bien que cela soit vrai, de nombreux points de repère montrent que la différence n'est pas trop grande.

Pour activer la journalisation dans MySQL version 5.1.6, vous utilisez le log_slow_queries et peut spécifier un fichier avec slow_query_log_file global. Cela peut être fait à l’invite d’exécution comme suit:

bash set global log_slow_queries = 1; set global slow_query_log_file = /dev/slow_query.log;

Vous pouvez définir cela de manière persistante dans le /etc/my.cnf ou my.ini fichier de configuration pour votre serveur.

bash log_slow_queries = 1; slow_query_log_file = /dev/slow_query.log;

Après avoir apporté cette modification, vous devez redémarrer le serveur MySQL, par exemple. service mysql redémarrer sur les systèmes Linux.

Dans le plus récent MySQL 5.6.1, log_slow_queries est obsolète et slow_query_log est utilisé à la place. Permettant TABLE comme type de sortie permet une expérience de débogage beaucoup plus agréable et peut être fait comme suit dans MySQL 5.6.1 et versions ultérieures:

bash log_output = TABLE; log_queries_not_using_indexes = 1; long_query_time = 1

long_query_time spécifie le nombre de secondes pendant lequel une requête lente est classée. La valeur par défaut est 10 et le minimum 0. Il peut prendre des valeurs en millisecondes en spécifiant un float; ici je l'ai réglé à 1 seconde. Donc, toute requête prenant plus de 1 seconde va être enregistrée dans le TABLE format de sortie.

Cela va se connecter à la mysql.slow_log et mysql.general_log tables à l'intérieur MySQL.

Pour désactiver la journalisation, définissez log_output à AUCUN.

log_queries_not_using_indexes est un booléen utile qui, lorsqu'il est activé en conjonction avec le journal de requête lent, signifie que seules les requêtes censées extraire toutes les lignes sont consignées.

Cette option ne signifie pas toujours qu'aucun index n'est utilisé. Par exemple, lorsqu'une requête utilise une analyse d'index complète, celle-ci est consignée car l'index ne limite pas le nombre de lignes..

Connexion en production?

L'activation de la journalisation sur un site de production avec du trafic devra presque toujours être effectuée pendant une courte période, tout en surveillant la charge pour s'assurer qu'elle n'affecte pas le service. Si vous êtes lourdement chargé et avez besoin d’une solution urgente, commencez par traiter le problème à l’invite avec AFFICHER LA LISTE DE PROCESSUS ou via le information_schema.PROCESSLIST table directement, par exemple. select * from information_schema.PROCESSLIST;.

La consignation de toutes les requêtes en production peut vous en dire beaucoup et constitue une bonne pratique à des fins de recherche lorsque vous auditez un projet, mais le laisser fonctionner plusieurs jours de suite ne vous donnera souvent pas plus de données utilisables qu’au mieux 48 heures ( en moyenne, capturez au moins les heures de pointe d'utilisation afin de bien examiner les requêtes et de vous faire une idée de la fréquence).

Remarque: si vous exploitez un site qui connaît des pics de trafic et des périodes de très faible fréquentation (comme un site Web sportif pendant et hors saison), soyez logique avec la manière dont vous envisagez la journalisation. Ne présumez pas que le site fonctionne rapidement. Faites un audit et, surtout, configurez des graphiques.

Journalisation et pt-query-digest de Percona

Percona dispose d’excellents outils, et pt-query-digest est un outil de ligne de commande pour l'analyse des journaux de requête, de la liste de processus ou de tcpdumps.

Vous pouvez utiliser pt-query-digest de la manière suivante:

Analysez un fichier * .log (généré à partir de votre journalisation de requête lente, par exemple):

bash $ pt-query-digest slow.log

Rapport sur les requêtes les plus lentes de host1 en temps réel (très utile!):

bash $ pt-query-digest --processlist h = hôte1

Utilisez tcpdump pour signaler les requêtes les plus lentes à partir des données du protocole MySQL:

"bash $ tcpdump -s 65535 -x -nn -q -tttt -i n’importe quel -c 1000 port 3306> mysql.tcp.txt

$ pt-query-digest -type tcpdump mysql.tcp.txt "

Enfin, nous pouvons enregistrer des données de requête lentes d’un hôte à un autre pour une révision ultérieure. Ici, nous enregistrons le résumé de la requête de slow.log dans host2:

bash $ pt-query-digest --review h = hôte2 --no-report slow.log

Pour apprendre à utiliser pleinement le pt-query-digest outil de Percona, lisez la page de manuel.

Représentation graphique de MySQL et des performances du serveur

Ce graphique des opérations de ligne InnoDB montre les opérations de ligne effectuées par InnoDB: mises à jour, lectures, suppressions et insertions..

C’est un sujet important et je vais juste en parler suffisamment dans ce guide pour vous permettre de démarrer avec la surveillance MySQL. Cependant, il est important de noter qu'en général, la surveillance de tous les services de votre site Web est idéale pour connaître réellement vos performances et vos usages..

Pour cela, je vous recommande de créer un RRDTool-solution basée telle que Cactus avec une configuration MySQL. Obtenez un modèle pour Cacti des gars de Percona.

Une fois que vous avez configuré Cacti et que vous pouvez commencer à analyser votre application, laissez un peu de temps pour permettre aux graphiques de se constituer. Après quelques jours, vous commencerez à voir les rythmes de votre trafic jour et nuit et à voir à quel point le serveur est vraiment occupé..

Si vous recherchez des alertes et des déclencheurs automatisés, envisagez de configurer monit, un moniteur proactif à code source ouvert pour les systèmes Unix. Avec monit, vous pouvez créer des règles pour votre serveur et vous assurer que vous êtes alerté lorsque la charge augmente, afin que vous puissiez la détecter pendant qu'elle se produit..

Journal de requête lent

L'enregistrement de toutes les requêtes lentes qui prennent plus d'une seconde à terminer peut nous dire quelque chose, mais il est tout aussi important de savoir quelles requêtes s'exécutent des centaines de fois. Même si l'exécution de ces requêtes est courte, la surcharge des requêtes les plus lourdes pèse lourdement sur le serveur..

C'est pourquoi rester au moment de mettre à jour quelque chose et de le mettre en ligne est le moment le plus crucial pour tout nouveau travail ou modification de base de données. Mes équipes ont toujours pour politique de ne jamais synchroniser les modifications apportées à la base de données de fonctionnalités après un mercredi sur un projet réel. Cela doit être fait au début de la semaine, au plus tard mardi, afin que toutes les équipes puissent surveiller et apporter un soutien en conséquence..

Avant de mettre en ligne de nouvelles requêtes, vous devez effectuer une analyse comparative avec un outil de test de charge tel que un B. Lorsque vous exécutez la référence, vous devez afficher le AFFICHER LA LISTE DE PROCESSUS, et permettant également la journalisation et la surveillance avec des outils système tels que Haut, libre et iostat. Il s'agit d'une étape cruciale avant de placer une nouvelle requête dans une production en direct. Mais ce n’est pas un test à 100% d’acide, car le trafic réel peut se comporter différemment d’un repère calculé..

À comparer avec un B, assurez-vous que le paquet est installé, par exemple:

bash utilisateurs #centos $ sudo yum install ab # utilisateurs de debian / ubuntu $ sudo apt-get install ab

Maintenant, vous pouvez commencer par tester votre application, par exemple:

bash $ ab -k -c 350 -n 20000 my-domain.com/

le -k des moyens pour rester en vie la connexion et le -c 350 est le nombre de connexions simultanées, c’est-à-dire le nombre de personnes / clients qui vont accéder au site en même temps. Finalement, le -n 20000 est le nombre de demandes qui seront faites à mon-domaine.com.

Donc, en exécutant la commande ci-dessus, vous frapperez http://my-domain.com/ avec 350 connexions simultanées jusqu'à ce que 20 000 demandes soient satisfaites, et vous utiliserez l'en-tête Keep Alive..

Une fois les 20 000 demandes terminées, vous recevrez un retour d'informations sur les statistiques. Cela vous indiquera la performance du site sous le stress que vous lui avez attribué lors de l'utilisation des paramètres ci-dessus. C'est un bon moyen de savoir de manière automatisée si votre requête a changé quelque chose.

Analyse comparative chaud / froid

Le montant de la demande et la charge du serveur ont un impact considérable sur les performances, ce qui peut affecter le temps de requête. Dans l’ensemble, vous devez activer le journal de requête lent pour qu’il capture ce problème en production, et en règle générale pour le développement, vous devez vous assurer que toutes les requêtes s’exécutent en fractions de milliseconde (0,0xx ou plus rapide) sur un serveur inactif..

Exécution Memcache aura un impact considérable sur vos exigences de charge et sera utilisé pour décharger sérieusement des ressources qui étaient en train d’être traitées. Assurez-vous d'utiliser Memcached efficacement et comparez votre application avec un cache chaud (préchargé avec des valeurs) par rapport à un cache froid.

Pour éviter de passer à la production avec un cache vide, un script de préchargement est un bon moyen de garantir que le cache sera lu et que vous ne recevrez pas un grand nombre de demandes toutes en même temps lors du retour d'un temps d'arrêt en raison de pannes de surcapacité.

Correction de requêtes lentes

Donc, après avoir activé la journalisation, vous avez maintenant trouvé des requêtes lentes dans votre application. Allons les réparer! À titre d'exemple, je vais démontrer divers problèmes courants que vous allez rencontrer et la logique pour les résoudre..

Si vous n'avez pas encore trouvé de requêtes lentes, alors vérifiez peut-être quels sont vos paramètres pour la long_query_time si vous utilisez la méthode de consignation des requêtes. Sinon, après avoir vérifié toutes vos requêtes avec le profilage (set profiling = 1), dressez une liste des requêtes prenant plus de fractions de millisecondes (0,000 x secondes) et commençons par celles-ci..

Problèmes communs

Voici six problèmes courants rencontrés lors de l'optimisation de requêtes MySQL:

1. COMMANDÉ PAR en utilisant filesort.

sql mysql> expliquer sélectionner * des produits où produits.prix> 4 et produits.stock> 0 classés par nom; + ---- + ------------- + ---------- + ------ + ------------ --- + ------ + --------- + ------ + ------ + --------------- -------------- + | id | select_type | table | type | possible_keys | clé | key_len | ref | rangées | Extra | + ---- + ------------- + ---------- + ------ + ------------ --- + ------ + --------- + ------ + ------ + --------------- -------------- + | 1 | SIMPLE | produits | TOUS | NULL | NULL | NULL | NULL | 1142 | Utiliser où; Utiliser le porte-fichiers | +----+-------------+----------+------+---------------+------+---------+------+------+-----------------------------+

Éviter le tri sur cela est impossible à cause de la ORDRE PAR NOM. Peu importe la permutation d’indice que vous utilisez, le mieux que vous obtiendrez est Utiliser où; Utilisation de Filesort dans ton Supplémentaire colonne. Pour optimis