Optimisation des performances MYSQL

Table des matières

Pourquoi effectuer une optimisation de base de données ?

optimisation de la base de données MySQL

Optimisation SQL et index

Installation et désinstallation de MySQL (installation et désinstallation en ligne de Linux)

Sélection de la version de la base de données

Préparer les données

relation entre la structure et la table

Comment repérer le SQL problématique

Vérifiez si le journal de vérification lente est activé :

Afficher les informations variables de tous les journaux

Format de stockage du journal de vérification lente MySQL

Outil d'analyse des journaux de vérification lente MySQL (mysqldumpslow)

introduire

usage

Outil d'analyse des journaux de requêtes lentes MySQL (pt-query-digest)

Introduction et fonction

Installer l'outil pt-query-digest

Installation rapide (remarque : wget doit être installé en premier)

Vérifiez si l'installation est terminée :

Introduction à l'utilisation de l'outil :

Comment trouver du SQL problématique en vérifiant lentement les journaux

SQL avec de nombreuses requêtes et chaque requête prend beaucoup de temps

IO grand SQL

SQL pour les erreurs d'index

Analyser le plan d'exécution SQL via une requête d'explication

Utiliser expliquer pour interroger le plan d'exécution SQL

Description de chaque champ :

Cas d'optimisation pour des requêtes lentes spécifiques

Optimisation de la fonction Max()

Optimisation de la fonction Count()

Optimisation des sous-requêtes

Optimisation du groupe par

Optimisation de la requête Limite

Optimisation de l'index


Pourquoi effectuer une optimisation de base de données ?

1. Évitez les erreurs d'accès aux pages du site Web

        Erreur Page 5xx due à l'expiration du délai de connexion à la base de données

        La page ne peut pas se charger en raison d'une requête lente

        Les données ne peuvent pas être soumises en raison du blocage

2. Augmenter la stabilité de la base de données

        De nombreux problèmes de base de données sont causés par des requêtes inefficaces

3. Optimiser l'expérience utilisateur

        Vitesse d'accès aux pages fluide

        Bonne expérience des fonctionnalités du site Web

optimisation de la base de données MySQL

Sous quels aspects la base de données peut-elle être optimisée ? Comme indiqué ci-dessous:

1.SQL et optimisation des index

        Écrivez du bon SQL en fonction des exigences et créez des index efficaces. Pour atteindre une certaine exigence, vous pouvez l'écrire de plusieurs manières. À ce stade, nous devons choisir la méthode d'écriture la plus efficace. À l'heure actuelle, vous devez comprendre l'optimisation SQL

2. Optimisation de la structure des tables de base de données

        Concevoir la structure de la table selon le paradigme de la base de données.La bonne conception de la structure de la table est directement liée à l'écriture d'instructions SQL.

3. Optimisation de la configuration du système

        La plupart fonctionnent sur des machines Linux, telles que des restrictions sur le nombre de connexions TCP, des restrictions sur le nombre de fichiers ouverts et des restrictions de sécurité, nous devons donc optimiser ces configurations en conséquence.

4. Optimisation de la configuration matérielle

        Choisissez un processeur adapté aux services de base de données, des E/S plus rapides et une mémoire plus élevée ; plus de processeurs ne sont pas toujours meilleurs, certaines versions de bases de données ont des limitations maximales et les opérations d'E/S ne réduisent pas le blocage.

Remarque : La figure ci-dessus montre que dans la pyramide, le coût de l'optimisation augmente progressivement de bas en haut, tandis que l'effet de l'optimisation diminue progressivement.

Optimisation SQL et index

Installation et désinstallation de MySQL (installation et désinstallation en ligne de Linux)

Sélection de la version de la base de données

1. Vérifiez la version de la base de données

select @@version;

Préparer les données

URL : https://dev.mysql.com/doc/sakila/en/sakila-installation.html

Les fichiers contenus dans le package compressé sakila-db.zip sont expliqués ci-dessous

Télécharger les données

Les étapes sont comme indiqué ci-dessous

 

relation entre la structure et la table

Remarque : Cette relation de structure de table est générée à l'aide d'outils.

Comment repérer le SQL problématique

Comment ouvrir le journal de vérification lente de MySQL et le format de stockage

Vérifiez si le journal de vérification lente est activé :

show variables like 'slow_query_log'

show variables like 'slow_query_log'  

//查看是否开启慢查询日志

set global slow_query_log_file=' /usr/share/mysql/sql_log/mysql-slow.log'

//慢查询日志的位置

set global log_queries_not_using_indexes=on;

//开启慢查询日志

set global long_query_time=1;  

//大于1秒钟的数据记录到慢日志中,如果设置为默认0,则会有大量的信息存储在磁盘中,磁盘很容易满掉

Afficher les informations variables de tous les journaux

show variables like '%log%'

mysql> show variables like '%log%';

+-----------------------------------------+------------------------------------+

| Variable_name                           | Value                              |

+-----------------------------------------+------------------------------------+

| back_log                                | 80                                 |

| binlog_cache_size                       | 32768                              |

| binlog_checksum                         | CRC32                              |

| binlog_direct_non_transactional_updates | OFF                                |

| binlog_error_action                     | IGNORE_ERROR                       |

| binlog_format                           | STATEMENT                          |

| binlog_gtid_simple_recovery             | OFF                                |

| binlog_max_flush_queue_time             | 0                                  |

| binlog_order_commits                    | ON                                 |

| binlog_row_image                        | FULL                               |

| binlog_rows_query_log_events            | OFF                                |

| binlog_stmt_cache_size                  | 32768                              |

| binlogging_impossible_mode              | IGNORE_ERROR                       |

| expire_logs_days                        | 0                                  |

| general_log                             | OFF                                |

| general_log_file                        | /var/lib/mysql/mysql-host.log      |

| innodb_api_enable_binlog                | OFF                                |

| innodb_flush_log_at_timeout             | 1                                  |

| innodb_flush_log_at_trx_commit          | 1                                  |

| innodb_locks_unsafe_for_binlog          | OFF                                |

| innodb_log_buffer_size                  | 8388608                            |

| innodb_log_compressed_pages             | ON                                 |

| innodb_log_file_size                    | 50331648                           |

| innodb_log_files_in_group               | 2                                  |

| innodb_log_group_home_dir               | ./                                 |

| innodb_mirrored_log_groups              | 1                                  |

| innodb_online_alter_log_max_size        | 134217728                          |

| innodb_undo_logs                        | 128                                |

| log_bin                                 | OFF                                |

| log_bin_basename                        |                                    |

| log_bin_index                           |                                    |

| log_bin_trust_function_creators         | OFF                                |

| log_bin_use_v1_row_events               | OFF                                |

| log_error                               | /var/log/mysqld.log                |

| log_output                              | FILE                               |

| log_queries_not_using_indexes           | ON                                 |

| log_slave_updates                       | OFF                                |

| log_slow_admin_statements               | OFF                                |

| log_slow_slave_statements               | OFF                                |

| log_throttle_queries_not_using_indexes  | 0                                  |

| log_warnings                            | 1                                  |

| max_binlog_cache_size                   | 18446744073709547520               |

| max_binlog_size                         | 1073741824                         |

| max_binlog_stmt_cache_size              | 18446744073709547520               |

| max_relay_log_size                      | 0                                  |

| relay_log                               |                                    |

| relay_log_basename                      |                                    |

| relay_log_index                         |                                    |

| relay_log_info_file                     | relay-log.info                     |

| relay_log_info_repository               | FILE                               |

| relay_log_purge                         | ON                                 |

| relay_log_recovery                      | OFF                                |

| relay_log_space_limit                   | 0                                  |

| simplified_binlog_gtid_recovery         | OFF                                |

| slow_query_log                          | OFF                                |

| slow_query_log_file                     | /var/lib/mysql/mysql-host-slow.log |

| sql_log_bin                             | ON                                 |

| sql_log_off                             | OFF                                |

| sync_binlog                             | 0                                  |

| sync_relay_log                          | 10000                              |

| sync_relay_log_info                     | 10000                              |

+-----------------------------------------+------------------------------------+

61 rows in set (0.01 sec)

Activer le journal de vérification lente :

show variables like 'slow_query_log'  
//查看是否开启慢查询日志
set global slow_query_log_file=' /var/lib/mysql/mysql-host-slow.log '
//慢查询日志的位置
set global log_queries_not_using_indexes=on;
//开启慢查询日志
set global long_query_time=1;  
//大于1秒钟的数据记录到慢日志中,如果设置为默认0,则会有大量的信息存储在磁盘中,磁盘很容易满掉

Vérifiez si le journal des requêtes lentes est activé :

En opération MySQL,

show databases;
use sakila;
select * from store;
select * from staff;

Surveillez le fichier journal pour voir s'il est écrit

tail -50f /var/lib/mysql/mysql-host-slow.log

Format de stockage du journal de vérification lente MySQL

Comme indiqué ci-dessous:

illustrer:

1. # Heure : 180526 1:06:54 ------->Durée d'exécution de la requête

2. # User@Host : root[root] @ localhost [] Id : 4 ------->Informations sur l'hôte pour l'exécution de SQL

3. # Query_time : 0,000401 Lock_time : 0,000105 Rows_sent : 2 Rows_examined : 2------->Informations d'exécution SQL :

Query_time : heure de la requête SQL

Lock_time : heure de verrouillage

Rows_sent : nombre de lignes envoyées

Rows_examined : le nombre de lignes analysées par le verrou

4. SET timestamp=1527268014 ; ------->Temps d'exécution SQL

5. Sélectionnez * dans le personnel ; ------->Contenu de l'exécution SQL

Outil d'analyse des journaux de vérification lente MySQL ( mysqldumpslow )

introduire

        Comment afficher le journal des requêtes lentes ? Si le journal des requêtes lentes est activé, de nombreuses données seront générées. Nous pouvons ensuite analyser le journal, générer un rapport d'analyse, puis optimiser via le rapport.

usage

Voyons ensuite l'utilisation de cet outil :

Remarque : sur le serveur où se trouve la base de données mysql, pas dans la ligne de commande mysql >

Comment utiliser cet outil:

mysqldumpslow -h 

Afficher des informations détaillées

M ysqldump lent -v

Affichez les 10 principaux journaux de requêtes lentes. Les résultats de l'analyse mysqldumpslow sont les suivants :

mysqldumpslow -t 10 /var/lib/mysql/mysql-slow.log

Les deux images ci-dessus sont les résultats de l'analyse. Chaque résultat indique le temps d'exécution, le temps de verrouillage, le nombre de lignes envoyées et le nombre de lignes analysées.

Cet outil est l'outil le plus couramment utilisé. Il est installé en installant MySQL. Cependant, les résultats statistiques de cet outil sont relativement peu nombreux et les données sur nos performances de verrouillage d'optimisation sont encore relativement faibles.

Outil d'analyse des journaux de requêtes lentes MySQL (pt-query-digest)

Introduction et fonction

        En tant qu'excellent administrateur de base de données MySQL, vous devez également maîtriser plusieurs outils de gestion MySQL utiles. J'ai donc organisé et recherché des outils pouvant faciliter la gestion de MySQL. Au cours de la prochaine période, une grande partie de l’énergie sera consacrée à la recherche de ces outils.

        La gestion des performances a toujours été la première priorité. La gestion de nombreuses tâches de DBA ne peut pas voir et n'a aucun moyen de mesurer la valeur. Cependant, si un système est aussi lent qu'un escargot, DBA peut restaurer le système au bord de l'effondrement grâce à la surveillance. et le réglage. Ramenez-nous à l’ère du train à grande vitesse. La valeur et le toucher devraient être énormes. (De nombreux dirigeants d'entreprise pensent que si le système ne peut plus fonctionner, ils doivent le remplacer par un processeur plus rapide, une mémoire plus grande et un stockage plus rapide, et ce n'est pas une minorité. Par conséquent, la valeur d'un administrateur de base de données n'a pas été reflétée, et le salaire n'est naturellement pas. sera très élevé)

        Le journal MySQL est le moyen le plus rapide et le plus direct de suivre les goulots d'étranglement des performances MySQL. Lorsqu'un goulot d'étranglement des performances du système se produit, vous devez d'abord ouvrir le journal des requêtes lentes et le suivre. Pendant cette période, la gestion et l'affichage du journal des requêtes lentes ont été trié deux fois. article, j'ai accidentellement découvert un autre outil pour afficher les journaux de requêtes lentes : mk-query-digest. Cet outil est connu comme l'un des dix meilleurs outils que les DBA MySQL doivent maîtriser sur Internet.

Installer l'outil pt-query-digest

Installation rapide (remarque : wget doit être installé en premier)

wget https://www.percona.com/downloads/percona-toolkit/2.2.16/RPM/percona-toolkit-2.2.16-1.noarch.rpm && yum localinstall -y percona-toolkit-2.2.16-1 .norch.rpm

Vérifiez si l'installation est terminée :

 Entrez : pt-summary sur la ligne de commande

L'affichage est le suivant : l'installation est réussie ! Entrez [[root@node03 mysql]# pt-query-digest --help] 

Introduction à l'utilisation de l'outil :

pt-résumé – aide

wget http://percona.com/get/pt-summary

Afficher les informations sur le serveur

Commande : pt-résumé

Afficher les informations sur l'utilisation du disque

Commande : pt-diskstats

Afficher les informations de la base de données MySQL

Instruction : pt-mysql-summary --user=root --password=123456

Analyser les journaux de requêtes lentes

Commande : pt-query-digest /data/mysql/data/db-3-12-slow.lo

Trouver la base de données esclave et l'état de synchronisation de MySQL

Instruction : pt-slave-find --host=localhost --user=root --password=123456

Afficher les informations sur le blocage de MySQL

pt-deadlock-logger --user=root --password=123456 localhost

Analyser l'utilisation de l'index à partir des journaux de requêtes lentes

pt-index-usage slow_20131009.log

Rechercher les index en double dans les tables de base de données

pt-duplicate-key-checker --host=localhost --user=root --password=123456

Afficher la surcharge d'E/S active actuelle pour les tables et fichiers MySQL

profil pt-io

Afficher les différences entre les différents fichiers de configuration MySQL

pt-config-diff /etc/my.cnf /etc/my_master.cnf

pt-find trouve la table mysql et exécute la commande. L'exemple est le suivant

Recherchez des tables de taille supérieure à 2 G dans la base de données :

pt-find --user=root --password=123456 --tablesize +2G

Retrouvez la table créée il y a 10 jours dans le moteur MyISAM :

pt-find --user=root --password=123456 --ctime +10 --engine MyISAM

Afficher les tailles des tables et des index et les trier

pt-find --user=root --password=123456 --printf "%T\t%D.%N\n" | trier -rn

pt-kill tue le processus MySQL qui répond à la norme

Afficher les requêtes qui prennent plus de 60 secondes

pt-kill --user=root --password=123456 --busy-time 60 --print

Tuer les requêtes de plus de 60 secondes

 pt-kill --user=root --password=123456 --busy-time 60 --kill

Afficher l'autorisation MySQL

1 pt-show-grants --user=root --password=123456

2 pt-show-grants --user=root --password=123456 --separate –revoke

Vérifier l'intégrité de la réplication de la base de données

pt-table-checksum --user=root --password=123456

annexe:

Comment trouver du SQL problématique en vérifiant lentement les journaux

SQL avec de nombreuses requêtes et chaque requête prend beaucoup de temps

        Ce sont généralement les premières requêtes analysées par pt-query-digest ; cet outil peut voir clairement le nombre et le pourcentage de chaque SQL exécuté. Le SQL qui est exécuté plus de fois et représente une plus grande proportion

IO grand SQL

        Faites attention à l'élément d'examen des lignes dans l'analyse pt-query-digest. Plus il y a de lignes analysées, plus les E/S sont importantes.

SQL pour les erreurs d'index

        Faites attention à la comparaison entre Rows examine et Rows Send dans l'analyse pt-query-digest. Cela signifie que le taux de réussite de l'index de ce SQL n'est pas élevé.Nous devons accorder une attention particulière à ce type de SQL.

Analyser le plan d'exécution SQL via une requête d'explication

Utiliser expliquer pour interroger le plan d'exécution SQL

Le plan d'exécution de SQL reflète l'efficacité d'exécution de SQL.La méthode d'exécution spécifique est la suivante :

Ajoutez simplement le mot-clé expliquer devant le SQL exécuté ;

Description de chaque champ :

1) Plus le nombre dans la colonne id est grand, plus il sera exécuté rapidement. Si les nombres sont identiques, ils seront exécutés de haut en bas. Si la colonne id est nulle, cela signifie qu'il s'agit d'un ensemble de résultats. , et il n'est pas nécessaire de l'utiliser pour les requêtes.

2) Les colonnes select_type courantes incluent :

A : simple : indique une requête de sélection simple qui ne nécessite pas d'opérations d'union ou ne contient pas de sous-requêtes. Lorsqu'il y a une requête de connexion, la requête externe est simple et il n'y en a qu'une seule

B : primaire : une sélection qui nécessite une opération d'union ou contient une sous-requête. Le type de sélection de la requête d'unité la plus externe est primaire. et un seul

C : Union : deux requêtes de sélection connectées par union. La première requête est une table dérivée dérivée. À l'exception de la première table, le type de sélection de la deuxième table et des tables suivantes est union.

D : union dépendante : identique à union, apparaît dans l'instruction union ou union all, mais cette requête sera affectée par une requête externe

E : Résultat de l'union : L'ensemble de résultats contenant union. Dans les instructions union et union all, car il n'a pas besoin de participer à la requête, le champ id est nul.

F : sous-requête : À l'exception de la sous-requête contenue dans la clause from, les sous-requêtes apparaissant ailleurs peuvent être des sous-requêtes.

G : sous-requête dépendante : similaire à l'union dépendante, indiquant que la requête de cette sous-requête sera affectée par la requête de la table externe

H : dérivé : la sous-requête qui apparaît dans la clause from est également appelée table dérivée. Dans d'autres bases de données, elle peut être appelée vue en ligne ou sélection imbriquée.

3)tableau

Nom de la table de requête affichée. Si la requête utilise un alias, celui-ci est affiché ici. S'il n'implique pas le fonctionnement de la table de données, il est affiché comme NULL. S'il est affiché sous la forme <N dérivé> entouré de crochets angulaires, cela signifie qu'il s'agit d'une table temporaire, le N suivant est l'identifiant dans le plan d'exécution, indiquant que les résultats proviennent de cette requête. S'il s'agit de <union M,N> entre crochets, il est similaire à <derived N> et est également une table temporaire, indiquant que le résultat provient de l'ensemble de résultats avec l'identifiant M,N de la requête d'union.

4) tapez

Du meilleur au pire : system, const, eq_ref, ref, fulltext, ref_or_null, unique_subquery, index_subquery, range, index_merge, index, ALL, sauf all, d'autres types peuvent utiliser index, sauf index_merge, other Un seul index peut être utilisé pour le taper

R : système : il n'y a qu'une seule ligne de données dans la table ou c'est une table vide, et elle ne peut être utilisée que pour les tables myisam et mémoire. S'il s'agit d'une table de moteur Innodb, la colonne type dans ce cas est généralement all ou index.

B : const : lors de l'utilisation d'un index unique ou d'une clé primaire, l'enregistrement renvoyé doit être une condition équivalente à 1 ligne d'enregistrements, généralement le type est const. D'autres bases de données sont également appelées analyses d'index uniques

C: eq_ref : apparaît dans le plan de requête pour être connecté à deux tables. La table pilote ne renvoie qu'une seule ligne de données, et cette ligne de données est la clé primaire ou l'index unique de la deuxième table et ne doit pas être nulle. Le l'index unique et la clé primaire sont constitués de plusieurs colonnes, eq_ref n'apparaîtra que lorsque toutes les colonnes sont utilisées à des fins de comparaison

D: ref : Il ne nécessite pas l'ordre de connexion comme eq_ref, et il n'y a aucune exigence de clé primaire et d'index unique. Cela peut se produire tant que des conditions égales sont utilisées pour la récupération et que les recherches d'égalité avec des index auxiliaires sont courantes. Ou dans une clé primaire multi-colonnes ou un index unique, l'utilisation de colonnes autres que la première colonne comme recherche de valeur égale peut également se produire. En bref, une recherche de valeur égale peut se produire lorsque les données renvoyées ne sont pas uniques.

E : texte intégral : récupération de l'index de texte intégral. Veuillez noter que la priorité de l'index de texte intégral est très élevée. Si l'index de texte intégral et l'index ordinaire existent en même temps, mysql donnera la priorité au texte intégral indice quel que soit le coût.

F : ref_or_null : similaire à la méthode ref, sauf que la comparaison des valeurs nulles est ajoutée. En fait, il n'est pas beaucoup utilisé.

G : unique_subquery : utilisé pour les sous-requêtes dans le formulaire où. La sous-requête renvoie des valeurs uniques sans valeurs en double.

H : index_subquery : utilisé pour les sous-requêtes dans le formulaire qui utilisent des index auxiliaires ou dans des listes de constantes. La sous-requête peut renvoyer des valeurs en double et l'index peut être utilisé pour dédupliquer la sous-requête.

I: range : analyse de plage d'index, couramment utilisée dans les requêtes utilisant des opérateurs tels que >, <, est nulle, entre, dans, comme, etc.

J : index_merge : indique que la requête utilise plus de deux index, et prend finalement l'intersection ou l'union. Les conditions communes et et ou utilisent des index différents. Le tri officiel est après ref_or_null, mais en fait, parce que tous les index doivent être lus, les performances peuvent ne pas être aussi bonnes que la portée la plupart du temps

K: index: Analyse complète de la table d'index, analyse l'index du début à la fin. Il est courant d'utiliser des colonnes d'index pour traiter des requêtes qui n'ont pas besoin de lire des fichiers de données, et d'utiliser des requêtes de tri ou de regroupement d'index.

L : tout : il s'agit d'analyser le fichier de données dans l'ensemble de la table, puis de le filtrer au niveau de la couche serveur pour renvoyer les enregistrements qui répondent aux exigences.

5)possible_keys

Les index pouvant être utilisés par la requête seront répertoriés ici.

6) clé

Interrogez l'index réellement utilisé. Lorsque select_type est index_merge, plus de deux index peuvent apparaître ici. Pour les autres select_types, un seul apparaîtra ici.

7) clé_len

Longueur de l'index utilisée pour traiter les requêtes. S'il s'agit d'un index à une seule colonne, la longueur entière de l'index est incluse. S'il s'agit d'un index à plusieurs colonnes, la requête ne pourra peut-être pas utiliser toutes les colonnes. Plus précisément, combien de colonnes les index sont utilisés, voici Il sera calculé. Les colonnes inutilisées ne seront pas calculées ici. Faites attention à la valeur de cette colonne et calculez la longueur totale de votre index multi-colonnes pour savoir si toutes les colonnes sont utilisées. Il est à noter que les index utilisés par la fonctionnalité ICP de MySQL ne seront pas comptés. De plus, key_len calcule uniquement la longueur de l'index utilisée dans la condition Where, et même si l'index est utilisé dans le tri et le regroupement, il ne sera pas calculé dans key_len.

8)réf

S'il s'agit d'une requête équivalente constante, const sera affiché ici. S'il s'agit d'une requête de connexion, le plan d'exécution de la table pilotée affichera les champs associés de la table pilotante. Si la condition utilise une expression ou une fonction, ou la condition La colonne a une erreur interne. Conversion implicite, qui peut apparaître comme func ici

9)lignes

Voici le nombre estimé de lignes de balayage dans le plan d'exécution, pas une valeur exacte

10) supplémentaire

Cette colonne peut afficher de nombreuses informations, il en existe des dizaines, les plus couramment utilisées sont

A : distinct : le mot-clé distinct est utilisé dans la partie de sélection

B : aucune table utilisée : requête sans clause from ou requête double From

C : Utilisez la sous-requête du formulaire not in() ou la requête de jointure de l'opérateur not exist. C'est ce qu'on appelle une anti-jointure. Autrement dit, une requête de jointure générale interroge d'abord la table interne, puis la table externe, tandis qu'une requête anti-jointure interroge d'abord la table externe, puis la table interne.

D : utilisation du tri de fichiers : cela se produit lorsque l'index ne peut pas être utilisé lors du tri. Couramment vu dans l'ordre par et grouper par les instructions

E : Utilisation de l'index : Il n'est pas nécessaire de renvoyer la table lors de l'interrogation. Les données interrogées peuvent être obtenues directement via l'index.

F : utilisation du tampon de jointure (boucle imbriquée par bloc), utilisation du tampon de jointure (accès par clé par lots) : les versions après 5.6.x optimisent les fonctionnalités BNL et BKA des requêtes associées. L'objectif principal est de réduire le nombre de boucles dans la table interne et d'analyser la requête de manière séquentielle.

G:en utilisant sort_union,en utilisant_union,en utilisant intersect,en utilisant sort_intersection:

using intersect : lors de l'expression des conditions de chaque index à l'aide de et, cette information indique que l'intersection est obtenue à partir des résultats du traitement.

using union : indique que lors de l'utilisation ou de la connexion des conditions de chaque index, cette information indique que l'union est obtenue à partir des résultats du traitement.

using sort_union et using sort_intersection : sont similaires aux deux précédents, sauf qu'ils apparaissent lors de l'utilisation de et et ou pour interroger une grande quantité d'informations. La clé primaire est d'abord interrogée, puis les enregistrements sont lus et renvoyés après tri et fusion.

H : using Temporary : Indique qu'une table temporaire est utilisée pour stocker les résultats intermédiaires. Les tables temporaires peuvent être des tables temporaires de mémoire et des tables temporaires de disque. Elles ne sont pas visibles dans le plan d'exécution. Vous devez vérifier les variables d'état, used_tmp_table et used_tmp_disk_table pour les voir.

I : en utilisant où : indique que tous les enregistrements renvoyés par le moteur de stockage ne répondent pas aux conditions de requête et doivent être filtrés au niveau de la couche serveur. Les conditions de requête sont divisées en conditions de restriction et conditions d'inspection.Avant la version 5.6, le moteur de stockage ne pouvait analyser et renvoyer les données qu'en fonction des conditions de restriction, puis la couche serveur filtrée en fonction des conditions d'inspection et renvoyait les données qui répondent réellement à la requête. Après la version 5.6.x, la fonctionnalité ICP est prise en charge et les conditions de vérification peuvent être transmises à la couche du moteur de stockage. Les données qui ne répondent pas aux conditions et restrictions de vérification ne seront pas lues directement, ce qui réduit considérablement le nombre d'enregistrements analysés par le moteur de stockage. La colonne supplémentaire montre l'utilisation de la condition d'index

J : firstmatch(tb_name) : une des nouvelles fonctionnalités d'optimisation des sous-requêtes introduite dans la version 5.6.x. Elle est courante dans les sous-requêtes contenant des clauses de type in() où. Si la quantité de données dans la table interne est relativement importante, cela peut se produire.

K : loosescan(m..n) : une des nouvelles fonctionnalités d'optimisation des sous-requêtes introduite après la version 5.6.x. Dans la sous-requête de type in(), cela peut se produire lorsque la sous-requête renvoie des enregistrements en double.

En plus de cela, il existe de nombreuses bibliothèques de dictionnaires de données de requête. Au cours du processus de plan d'exécution, certains messages d'invite indiquant que les résultats ne peuvent pas exister sont détectés.

11)filtré

Cette colonne apparaîtra lors de l'utilisation d'explication Extended. Les versions après 5.7 ont ce champ par défaut, il n'est donc pas nécessaire d'utiliser Explain Extended. Ce champ indique la proportion des enregistrements restants qui satisfont la requête une fois les données renvoyées par le moteur de stockage filtrées au niveau de la couche serveur. Notez qu'il s'agit d'un pourcentage et non d'un nombre spécifique d'enregistrements.

Photos ci-jointes :

Cas d'optimisation pour des requêtes lentes spécifiques

Optimisation de la fonction Max()

Objectif : Interroger l'heure du dernier paiement - optimiser la fonction max()

Déclaration:

select max(payment_date) from payment;

Plan de mise en œuvre:

explain select max(payment_date) from payment;


Vous pouvez constater que le plan d'exécution affiché n'est pas très efficace et peut ralentir l'efficacité du serveur. Comment l'optimiser ?

Créer un index

create index inx_paydate on payment(payment_date);

L'index est exploité de manière séquentielle et n'a pas besoin d'analyser la table, l'efficacité d'exécution sera donc relativement constante.

Optimisation de la fonction Count()

Condition : vérifier simultanément le nombre de films en 2006 et 2007 dans un seul SQL

Mauvaise façon:

Déclaration:

select count(release_year='2006' or release_year='2007') from film;

Je ne peux pas dire quels étaient les chiffres en 2006 et 2007.

 select count(*) from film where release_year='2006' or release_year='2007';

Façon correcte d'écrire :

select count(release_year='2006' or null) as '06films',count(release_year='2007' or null) as '07films' from film;

Différence : count(*) et count(id)

Créer une table et insérer une instruction

 create table t(id int);

 insert into t values(1),(2),(null);

Count(*):select count(*)from t;

Count(id):select count(id)from t;

illustrer:

Count(id) est une valeur qui ne contient pas null

Count(*) est une valeur contenant null

Optimisation des sous-requêtes

        La sous-requête est une méthode que nous utilisons souvent dans le processus de développement. Dans des circonstances normales, la sous-requête doit être optimisée en une requête de jointure. Cependant, lors de l'optimisation, vous devez faire attention à savoir si la clé associée a une relation un-à-plusieurs. , et faites attention aux données en double.

Voir la table T que nous avons créée

show create table t;

Ensuite, nous créons une table t1

create table t1(tid int);

et insérez une donnée

Nous devons effectuer une sous-requête. La condition requise est la suivante : interroger toutes les données de la table t dont l'identifiant est tid dans la table t1 ;

select * from t where t.id in (select t1.tid from t1);

Ensuite, nous utilisons l'opération de jointure pour effectuer l'opération

select id from t join t1 on t.id =t1.tid;

 À en juger par les résultats ci-dessus, les résultats de la requête sont cohérents, nous optimisons donc la sous-requête en une opération de jointure.

Ensuite, nous insérons une autre donnée dans la table t1

insert into t1 values (1);

select * from t1;

Dans ce cas, si nous utilisons une sous-requête pour interroger, le résultat renvoyé est le suivant :

Si vous utilisez la méthode join pour effectuer une recherche, comme indiqué dans la figure ci-dessous :

Dans ce cas, il existe une relation un-à-plusieurs, et il y aura une duplication des données. Afin d'éviter la duplication des données, nous devons utiliser le mot-clé distinct pour effectuer les opérations de déduplication.

select distinct id from t join t1 on t.id =t1.tid;

Remarque : Cette relation un-à-plusieurs est un écueil que nous avons rencontré au cours du processus de développement. La duplication des données se produit et tout le monde doit y prêter attention.

Exemple : Recherchez tous les films mettant en vedette Sandra :

explain select title,release_year,length

 from film

 where film_id in (

 select film_id from film_actor where actor_id in (

 select actor_id from actor where first_name='sandra'));

Optimisation du groupe par

Il est préférable d'utiliser les colonnes d'une même table,

Exigences : Le nombre de films auxquels chaque acteur a participé - (liste des films et liste des acteurs) 

explain select actor.first_name,actor.last_name,count(*)

from sakila.film_actor

inner join sakila.actor using(actor_id)

group by film_actor.actor_id;

SQL optimisé :

explain select actor.first_name,actor.last_name,c.cnt

from sakila.actor inner join (

select actor_id,count(*) as cnt from sakila.film_actor group by actor_id

)as c using(actor_id);

Remarque : à en juger par le plan d'exécution ci-dessus, cette méthode optimisée n'utilise pas de fichiers temporaires ni de tri de fichiers , mais utilise plutôt des index. L'efficacité des requêtes est très élevée.

À l'heure actuelle, les données de notre table sont relativement volumineuses, ce qui occupera de nombreuses opérations d'E/S, optimisera l'efficacité de l'exécution SQL et économisera les ressources du serveur, nous devons donc les optimiser.

Avis:

1. Le rôle du mot - clé using dans mysql : c'est - à - dire que pour utiliser using , le tableau a et le tableau b doivent avoir les mêmes colonnes .

2. Lorsque nous utilisons Join pour effectuer des requêtes conjointes sur plusieurs tables, nous utilisons généralement On pour établir la relation entre les deux tables. En fait, il existe un mot-clé plus pratique, Using.

3. Si les noms de champs associés aux deux tables sont identiques, vous pouvez utiliser Using pour établir la relation, qui est concise et claire.

Optimisation de la requête Limite

La limite est souvent utilisée pour le traitement de la pagination, et la durée est utilisée avec la clause order by, donc la plupart du temps, Filesorts est utilisé, ce qui entraînera de nombreux problèmes d'E/S.

exemple:

Condition : interrogez l'ID du film et les informations de description, triez en fonction du thème et récupérez 5 éléments de données à partir du numéro de série 50.

select film_id,description from sakila.film order by title limit 50,5;

Résultat de l'exécution :

Consultez son plan d’exécution :

 Quelle méthode d’optimisation doit-on utiliser pour cette opération ?

Étape d'optimisation 1 :

Utilisez des colonnes indexées ou des clés primaires pour effectuer des opérations de tri, car comme nous le savons tous, innodb trie selon l'ordre logique des clés primaires. De nombreuses opérations d'E/S peuvent être évitées.

select film_id,description from sakila.film order by film_id limit 50,5;

 Vérifier le plan d'exécution

 Donc, si nous obtenons 5 enregistrements à partir de la ligne 500, à quoi ressemblera le plan d'exécution ?

explain select film_id,description from sakila.film order by film_id limit 500,5\G

Au fur et à mesure que nous tournons la page, l'opération d'E/S deviendra de plus en plus grande. Si une table contient des dizaines de millions de lignes de données, la page tournera deviendra de plus en plus lente, nous devons donc l'optimiser davantage.

Étape d'optimisation 2 : enregistrez la clé primaire renvoyée la dernière fois et utilisez le filtrage par clé primaire dans la requête suivante. ( Remarque : cela évite d'analyser trop d'enregistrements lorsque la quantité de données est importante )

La dernière limite était de 50,5, nous devons donc utiliser la dernière valeur d'enregistrement d'index dans ce processus d'optimisation.

select film_id,description from sakila.film  where film_id >55 and film_id<=60 order by film_id limit 1,5;

Consultez le plan d'exécution :

 Conclusion : Le nombre de lignes de scan reste inchangé, le plan d'exécution est très fixe, et l'efficacité est également très fixe.

Précautions:

Les clés primaires doivent être triées de manière séquentielle et continue. S'il y a une certaine colonne ou plusieurs colonnes au milieu de la clé primaire, il y aura moins de 5 lignes de données répertoriées ; si ce n'est pas continu, créez une colonne supplémentaire index_id pour assurez-vous que cette colonne de données Si vous souhaitez l'augmenter automatiquement, ajoutez simplement un index.

Optimisation de l'index

1. Qu'est-ce qu'un indice ?

L'index est l'équivalent de la table des matières d'un livre. Vous pouvez trouver rapidement le contenu souhaité en fonction des numéros de page dans la table des matières.

La base de données utilise un index pour trouver une valeur spécifique, puis pointe vers l'avant pour trouver la ligne contenant cette valeur. Créez un index dans la table, puis recherchez la valeur d'index qui répond aux conditions de requête dans l'index, et enfin trouvez rapidement l'enregistrement correspondant dans la table via le ROWID (équivalent au numéro de page) enregistré dans l'index. L'établissement d'un index est un champ relativement directionnel dans la table, qui équivaut à un annuaire. Par exemple, l'indicatif régional administratif. Les indicatifs régionaux administratifs d'une même région sont tous identiques. Ajoutez ensuite un index à cette colonne pour Évitez les analyses répétées. Atteignez l'objectif d'optimisation !

2. Comment créer un index

Des index peuvent être créés lors de l'exécution de l'instruction CREATE TABLE, ou CREATE INDEX ou ALTER TABLE peuvent être utilisés seuls pour ajouter des index à la table.

1 ALTERTABLE

ALTER TABLE est utilisé pour créer un index normal, un index UNIQUE ou un index PRIMARY KEY.

ALTER TABLE table_name ADD INDEX index_name (column_list)

ALTER TABLE table_name ADD UNIQUE (column_list)

ALTER TABLE table_name ADD PRIMARY KEY (column_list)

Remarque : table_name est le nom de la table à indexer, column_list indique les colonnes à indexer, et s'il y a plusieurs colonnes, séparez-les par des virgules. Le nom d'index index_name est facultatif. Par défaut, MySQL attribuera un nom basé sur la première colonne d'index. De plus, ALTER TABLE permet de modifier plusieurs tables dans une seule instruction, de sorte que plusieurs index peuvent être créés en même temps.

2 CRÉER UN INDEX

CREATE INDEX peut ajouter des index ordinaires ou des index UNIQUE à la table.

CREATE INDEX index_name ON table_name (column_list)

CREATE UNIQUE INDEX index_name ON table_name (column_list)

Remarque : table_name, index_name et column_list ont la même signification que dans l'instruction ALTER TABLE et le nom de l'index n'est pas facultatif. De plus, vous ne pouvez pas utiliser l'instruction CREATE INDEX pour créer un index PRIMARY KEY.

3. Type d'index

Lorsque vous créez un index, vous pouvez spécifier si l'index peut contenir des valeurs en double. S’il n’est pas inclus, l’index doit être créé en tant qu’index PRIMARY KEY ou UNIQUE. Pour un index unique à colonne unique, cela garantit que la colonne unique ne contient pas de valeurs en double. Pour les index uniques multicolonnes, il est garanti que la combinaison de plusieurs valeurs ne se répète pas.

Les index PRIMARY KEY sont très similaires aux index UNIQUE.

En fait, un index PRIMARY KEY n’est qu’un index UNIQUE portant le nom PRIMARY. Cela signifie qu'une table ne peut contenir qu'une seule PRIMARY KEY, car il est impossible d'avoir deux index portant le même nom dans une table.

L'instruction SQL suivante ajoute un index PRIMARY KEY sur sid à la table des étudiants.

ALTER TABLE students ADD PRIMARY KEY (sid)

4. Supprimer l'index

Les index peuvent être supprimés à l'aide de l'instruction ALTER TABLE ou DROP INDEX. Semblable à l'instruction CREATE INDEX, DROP INDEX peut être traitée comme une instruction dans ALTER TABLE. La syntaxe est la suivante.
 

DROP INDEX index_name ON talbe_name

ALTER TABLE table_name DROP INDEX index_name

ALTER TABLE table_name DROP PRIMARY KEY

Parmi elles, les deux premières instructions sont équivalentes et l'index index_name dans table_name est supprimé.

La troisième instruction n'est utilisée que lors de la suppression de l'index PRIMARY KEY, car une table ne peut avoir qu'un seul index PRIMARY KEY, il n'est donc pas nécessaire de spécifier le nom de l'index. Si aucun index PRIMARY KEY n'est créé mais que la table possède un ou plusieurs index UNIQUE, MySQL supprime le premier index UNIQUE.

Si une colonne est supprimée d'une table, l'index sera affecté. Pour un index multi-colonnes, si l'une des colonnes est supprimée, la colonne sera également supprimée de l'index. Si vous supprimez toutes les colonnes qui composent l'index, l'intégralité de l'index sera supprimée.

   5. Afficher l'index

show index from tblname;

show keys from tblname;

   6. Dans quelles circonstances les index sont-ils utilisés ?

1. La clé primaire de la table

2. Créez automatiquement un index unique

3. Contraintes uniques sur les champs de table

4. Champs pour requête conditionnelle directe (champs utilisés pour les contraintes conditionnelles en SQL)

5. Champs associés aux autres tables de la requête

6. Les champs triés dans la requête (si les champs triés sont accessibles via l'index, la vitesse de tri sera grandement améliorée)

7. Champs de statistiques ou de statistiques de groupe dans les requêtes

8. Les enregistrements de la table sont trop peu nombreux (si une table ne contient que 5 enregistrements et qu'un index est utilisé pour accéder aux enregistrements, il faut d'abord accéder à la table d'index, puis à la table de données via la table d'index. Généralement, la table d'index et la table de données ne sont pas dans le même bloc de données)

9. Tables fréquemment insérées, supprimées ou modifiées (pour certaines tables métier fréquemment traitées, les index doivent être réduits autant que possible si les requêtes le permettent)

10. Champs de table avec des données répétées et une distribution uniforme (si une table contient 100 000 lignes d'enregistrements et qu'il existe un champ A qui n'a que deux valeurs : T et F, et que la probabilité de distribution de chaque valeur est d'environ 50 %, alors pour ce type de table A. La construction d'index sur des champs n'améliore généralement pas la vitesse de requête de la base de données.)

11. Champs de table souvent interrogés avec le champ principal mais comportant de nombreuses valeurs d'index de champ principal

12. Choses à faire lors de l'indexation de dizaines de millions de bases de données MySQL et comment améliorer les performances

3. Comment sélectionner les colonnes appropriées pour créer des index

1.  Ajoutez des index aux colonnes de la clause Where, de la clause group by, de la clause order by et de la clause on. 

2. Plus le champ d'index est petit, mieux c'est (parce que l'unité de stockage des données de la base de données est basée sur la "page", plus les données sont stockées, plus les IO seront grandes)

3. Les colonnes à grande dispersion sont placées devant l'index commun.

exemple:

select * from payment where staff_id =2 and customer_id =584;

Avis:

L'index ( staff_id , customer_id ) est-il meilleur ou l'index ( customer_id , staff_id ) meilleur ?

Alors comment vérifier la dispersion ?

A. Examinons d'abord la structure de la table

desc payment;

B. Vérifiez respectivement le nombre d'identifiants différents dans ces deux champs. Plus le nombre est grand, plus le degré de dispersion est grand : Par conséquent, comme le montre la figure ci-dessous : customer_id a un plus grand degré de dispersion.

Conclusion : Puisque customer_id est très discret, il est préférable d'utiliser index ( customer_id , staff_id )

C. index commun mysql

①Règles de dénomination : nom de la table_nom du champ

1. Les champs qui doivent être indexés doivent être dans la condition Where

2. Les champs contenant une petite quantité de données n'ont pas besoin d'être indexés

3. S'il existe une relation OU dans la condition Where, l'indexation ne fonctionnera pas.

4. Respecter le principe le plus à gauche

②Qu'est -ce qu'un indice commun ?

  1. Un index sur deux colonnes ou plus est appelé index conjoint, également appelé index composite.
  2. L'utilisation de colonnes supplémentaires dans un index vous permet de restreindre la portée de votre recherche, mais l'utilisation d'un index à deux colonnes  est différente de l'utilisation de deux index distincts. La structure d'un index composite est similaire à celle d'un annuaire téléphonique, dans lequel le nom d'une personne est composé d'un prénom et d'un nom. L'annuaire téléphonique est d'abord trié par paires de noms de famille, puis trié par prénom pour les personnes portant le même nom de famille. . Un annuaire téléphonique est très utile si vous connaissez votre nom de famille, plus utile si vous connaissez à la fois votre prénom et votre nom, mais inutile si vous ne connaissez que votre prénom mais pas de nom de famille.

Par conséquent, lors de la création d’un index composite, l’ordre des colonnes doit être soigneusement pris en compte. Les index composites sont utiles lors d'une recherche sur toutes les colonnes de l'index ou uniquement sur les premières colonnes ; ils ne sont pas utiles lors d'une recherche sur les colonnes suivantes.

4. Méthodes d' optimisation des index SQL

1. Maintenance et optimisation des index (index dupliqués et redondants)

L'augmentation des index sera bénéfique pour l'efficacité des requêtes, mais réduira l'efficacité de l'insertion, de la mise à jour et de la suppression. Cependant, ce n'est souvent pas le cas. Un trop grand nombre d'index affectera non seulement l'efficacité de l'utilisation, mais également l'efficacité des requêtes. est dû à la requête de la base de données. Lors de l'analyse, vous devez d'abord choisir l'index à utiliser pour la requête. S'il y a trop d'index, le processus d'analyse sera plus lent, ce qui réduira également l'efficacité de la requête. Par conséquent, nous devons savoir comment augmenter et parfois maintenir et supprimer ceux qui sont inutiles.

2. Comment trouver des index en double et redondants

Index en double :

Les index en double font référence aux index du même type construits sur les mêmes colonnes dans le même ordre. Les index sur les colonnes de clé primaire et d'ID dans le tableau suivant sont des index en double.

create table test(

id int not null primary key,

name varchar(10) not null,

title varchar(50) not null,

unique(id)

)engine=innodb;

Index redondant :

Un index redondant fait référence à un index avec la même colonne de préfixe dans plusieurs index, ou à un index qui contient la clé primaire dans un index conjoint. Dans l'exemple suivant, la clé (nom, identifiant) est un index redondant.

create table test(

id int not null primary key,

name varchar(10) not null,

title varchar(50) not null,

key(name,id)

)engine=innodb;

Remarque : Pour innodb, la clé primaire sera en fait incluse derrière chaque index. À ce stade, l'index conjoint que nous avons établi inclut artificiellement la clé primaire, il s'agit donc d'un index redondant pour le moment.

3. Comment trouver des index en double

Outils : utilisez l'outil pt-duplicate-key-checker pour vérifier les index en double et redondants.

pt-duplicate-key-checker -uroot -padmin -h 127.0.0.1

4. Méthodes de maintenance des index

En raison de changements commerciaux, certains index ne sont plus nécessaires et doivent être supprimés.

Dans MySQL, l'utilisation de l'index ne peut être analysée que via les journaux de requêtes lentes et l'outil pt-index-usage ;

pt-index-usage -uroot -padmin /var/lib/mysql/mysql-host-slow.lo

 Ci-joint : https://www.percona.com/downloads/

5. Choses à noter

Des index MySql bien conçus peuvent faire voler votre base de données et améliorer considérablement son efficacité. Il y a quelques points à noter lors de la conception d'index MySql :

1. Créez un index

Pour les applications où les requêtes dominent, les index sont particulièrement importants. Souvent, les problèmes de performances sont simplement dus au fait que nous oublions d’ajouter un index ou que nous n’ajoutons pas un index plus efficace. Si aucun index n'est ajouté, une analyse complète de la table sera effectuée pour trouver même une donnée spécifique. Si la quantité de données dans une table est importante et qu'il y a peu de résultats qualifiés, alors ne pas ajouter d'index entraînera une dégradation fatale des performances. . .

Mais il n'est pas nécessaire de créer un index dans toutes les situations. Par exemple, le sexe ne peut avoir que deux valeurs. Construire un index non seulement n'a aucun avantage, mais affecte également la vitesse de mise à jour. C'est ce qu'on appelle la surindexation.

2. Indice composite

Par exemple, il existe une instruction comme celle-ci : sélectionnez * parmi les utilisateurs où zone='beijing' et âge=22 ;

Si nous créons un seul index sur la zone et l'âge respectivement, puisque la requête MySQL ne peut utiliser qu'un seul index à la fois, bien que cela ait amélioré l'efficacité de âge , La création d'un index composite sur la colonne apportera une plus grande efficacité. Si nous créons un indice composite de (superficie, âge, salaire), cela équivaut en fait à créer trois indices (superficie, âge, salaire), (superficie, âge) et (superficie). C'est ce qu'on appelle la meilleure caractéristique du préfixe gauche. .

Par conséquent, lorsque nous créons un index composite, nous devons placer les colonnes les plus couramment utilisées comme contraintes à gauche, par ordre décroissant.

3. L'index ne contiendra pas de colonnes avec des valeurs NULL.

Tant qu'une colonne contient une valeur NULL, elle ne sera pas incluse dans l'index. Tant qu'une colonne de l'index composite contient une valeur NULL, alors cette colonne n'est pas valide pour l'index composite. Par conséquent, lors de la conception de la base de données, nous ne devons pas laisser la valeur par défaut du champ être NULL.

4. Utilisez des index courts

Pour indexer des colonnes de chaîne, une longueur de préfixe doit être spécifiée si possible. Par exemple, si vous avez une colonne CHAR(255), n'indexez pas la colonne entière si la plupart des valeurs sont uniques dans les 10 ou 20 premiers caractères. Les index courts améliorent non seulement la vitesse des requêtes, mais permettent également d'économiser de l'espace disque et des opérations d'E/S.

5. Problème d'index de tri

Les requêtes MySQL n'utilisent qu'un seul index, donc si un index a été utilisé dans la clause Where, les colonnes classées par n'utiliseront pas l'index. Par conséquent, n'utilisez pas d'opérations de tri lorsque le tri par défaut de la base de données peut répondre aux exigences ; essayez de ne pas inclure le tri de plusieurs colonnes. Si nécessaire, il est préférable de créer des index composites pour ces colonnes.

6. Opération d'instruction similaire

Dans des circonstances normales, l'utilisation d'opérations similaires est déconseillée . Si elle doit être utilisée, la manière de l'utiliser est également un problème. Comme « %aaa% » n'utilisera pas l'index mais comme « aaa% » utilisera l'index.

7. N'effectuez pas d'opérations sur les colonnes

sélectionnez * parmi les utilisateurs où

ANNÉE (ajouter)

8. N'utilisez pas le fonctionnement NON IN

Les opérations NOT IN n'utiliseront pas l'index et effectueront une analyse complète de la table. NOT IN peut être remplacé par NOT EXISTS

Je suppose que tu aimes

Origine blog.csdn.net/qq_40322236/article/details/129674310
conseillé
Classement