La colonne
Avant, un développeur est venu me voir et m'a dit qu'une certaine requête de fonction dans l'application était beaucoup plus lente qu'avant, et J'ai demandé au développeur de le fournir. Pour les instructions SQL lentes, je suis allé dans la base de données MySQL correspondante pour vérifier le plan d'exécution et j'ai constaté que le plan d'exécution était incorrect. La première réaction a été que les informations statistiques de l'une des tables étaient inexactes, ce qui. a rendu le plan d'exécution de l'instruction SQL incorrect. À partir de la requête SQL efficace, cela devient du SQL lent. Après avoir localisé le problème, il était naturel d'analyser et de collecter à nouveau les informations. À ce moment-là, j'ai constaté que toutes les sélections sur la table d'analyse étaient soudainement bloquées et ne renvoyaient aucun résultat. Ensuite, l'application a explosé avec divers messages d'alarme.
À cette époque, l'opération d'analyse était effectuée sur une bibliothèque esclave, qui était essentiellement une requête de sélection, donc ce qui est simulé ici est une opération de requête.
Créer une table de simulation
mysql> select * from t_test_1; +----+--------+-------+--------+ | id | name | name2 | status | +----+--------+-------+--------+ | 1 | name1 | 1001 | 0 | | 2 | name1 | 1002 | 1 | | 3 | name1 | 1003 | 1 | | 4 | name1 | 1004 | 0 | | 5 | name1 | 1005 | 1 | | 6 | name1 | 1006 | 0 | | 7 | name1 | 1007 | 2 | | 8 | name1 | 1008 | 0 | | 9 | name1 | 1009 | 1 | | 10 | name10 | 1001 | 0 | +----+--------+-------+--------+ 10 rows in set (0.00 sec)复制代码
Simuler une requête lente Étant donné que la quantité de données ici n'est pas suffisante, le sommeil est utilisé à la place. session1 : Simuler une requête lente
mysql> select sleep(1000) from t_test_1;复制代码
session2 : Simuler la collecte des statistiques de la table
mysql> analyze table t_test_1;复制代码
session3 : Après avoir simulé l'exécution de la commande d'analyse, exécutez une requête de sélection sur la table t_test_1
mysql> select * from t_test_1 where id=5;复制代码
session4 : Interrogez toutes les informations de session
mysql> select * from processlist order by time desc; +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ | 21 | root | localhost | testdb | Query | 242 | User sleep | select sleep(1000) from t_test_1 | | 23 | root | localhost | testdb | Query | 180 | Waiting for table flush | analyze table t_test_1 | | 24 | root | localhost | testdb | Query | 3 | Waiting for table flush | select * from t_test_1 where id=5 | | 22 | root | localhost | information_schema | Query | 0 | executing | select * from processlist order by time desc | +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ 4 rows in set (0.00 sec)复制代码
De toutes les informations de session obtenues à partir de la session4, vous pouvez voir que le statut de 2 sessions est "En attente de vidage de la table".
Lorsque la base de données MySQL effectue des opérations telles que FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE ou OPTIMIZE TABLE, cela entraînera la nécessité pour fermer la table mémoire et rouvrir la table pour charger la nouvelle structure de table en mémoire. Cependant, la fermeture d'une table nécessite d'attendre la fin de toutes les opérations sur la table (y compris la sélection, l'insertion, la mise à jour, le verrouillage de la table, etc.), donc lorsqu'une sélection particulièrement lente est exécutée, la commande d'analyse de table ne se terminera jamais.
Maintenant que vous savez ce qui cause l'attente du vidage de la table, commencez à localiser les instructions SQL lentes. Ici, vous pouvez voir que ce que nous exécutons est de collecter la table t_test_1, nous devons donc interroger une requête lente impliquant la table t_test_1, et le temps d'exécution est plus long que le temps d'exécution de la table d'analyse t_test_1.
mysql> select * from processlist where info like '%t_test_1%' and time >=(select time from processlist where id=23) order by time desc; +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ | 21 | root | localhost | testdb | Query | 1187 | User sleep | select sleep(1000) from t_test_1 | | 23 | root | localhost | testdb | Query | 1125 | Waiting for table flush | analyze table t_test_1 | +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ 2 rows in set (0.37 sec)复制代码
En utilisant l'instruction SQL ci-dessus, il est facile de localiser la session avec l'id=21, provoquant le blocage de la table d'analyse t_test_1, vous devez donc tuer la session 21.
mysql> kill 21; Query OK, 0 rows affected (0.01 sec) mysql> show full processlist; +----+------+-----------+--------------------+---------+------+----------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+--------------------+---------+------+----------+-----------------------+ | 22 | root | localhost | information_schema | Query | 0 | starting | show full processlist | | 23 | root | localhost | testdb | Sleep | 1205 | | NULL | | 24 | root | localhost | testdb | Sleep | 1028 | | NULL | +----+------+-----------+--------------------+---------+------+----------+-----------------------+ 3 rows in set (0.00 sec)复制代码
Tuez le séance, défaut Lift.
Suggestions de table d'analyse d'exécution de production 1. Avant l'exécution, estimez le volume de données de la table et estimez le temps requis en fonction de l'expérience. En même temps, vérifiez si un SQL lent collecte la table d'informations et si de longues transactions sont en cours d'exécution.
2. Évitez d'exécuter un tableau d'analyse pour collecter des informations statistiques pendant les périodes de pointe.
Plus de recommandations d'apprentissage gratuites connexes : tutoriel MySQL(vidéo)
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!