Indexation MySQL et optimisation des performances

MySQLMySQLBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, vous allez apprendre les index MySQL et les techniques d'optimisation des performances. Le laboratoire se concentre sur la création et la gestion d'index pour améliorer les performances des requêtes de base de données.

Vous commencerez par créer une table users et insérer des données d'exemple. Ensuite, vous créerez un index sur une seule colonne pour la colonne username et apprendrez à vérifier sa création. Le laboratoire couvrira également l'analyse des plans de requête à l'aide de EXPLAIN, l'ajout d'index composites pour les requêtes multi-colonnes et la suppression des index inutilisés pour maintenir l'efficacité de la base de données.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL mysql(("MySQL")) -.-> mysql/BasicKeywordsandStatementsGroup(["Basic Keywords and Statements"]) mysql(("MySQL")) -.-> mysql/AdvancedQueryingandOptimizationGroup(["Advanced Querying and Optimization"]) mysql(("MySQL")) -.-> mysql/SystemManagementToolsGroup(["System Management Tools"]) mysql/BasicKeywordsandStatementsGroup -.-> mysql/create_table("Table Creation") mysql/BasicKeywordsandStatementsGroup -.-> mysql/drop_table("Table Removal") mysql/BasicKeywordsandStatementsGroup -.-> mysql/alter_table("Table Modification") mysql/BasicKeywordsandStatementsGroup -.-> mysql/select("Data Retrieval") mysql/BasicKeywordsandStatementsGroup -.-> mysql/insert("Data Insertion") mysql/AdvancedQueryingandOptimizationGroup -.-> mysql/index("Index Management") mysql/SystemManagementToolsGroup -.-> mysql/show_status("Status Overview") subgraph Lab Skills mysql/create_table -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/drop_table -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/alter_table -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/select -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/insert -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/index -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} mysql/show_status -.-> lab-550910{{"Indexation MySQL et optimisation des performances"}} end

Créer un index sur une seule colonne d'une table

Dans cette étape, vous allez apprendre à créer un index sur une seule colonne en MySQL. Les index sont essentiels pour améliorer les performances des requêtes de base de données, en particulier lorsqu'il s'agit de tables volumineuses. Un index sur une colonne permet à la base de données de localiser rapidement les lignes correspondant à une valeur spécifique dans cette colonne, sans avoir à parcourir toute la table.

Comprendre les index

Imaginez un index comme l'index d'un livre. Au lieu de lire tout le livre pour trouver un sujet spécifique, vous pouvez utiliser l'index pour localiser rapidement les pages pertinentes. De même, un index de base de données aide le moteur de base de données à trouver rapidement des lignes spécifiques.

Créer une table

Tout d'abord, créons une simple table nommée users pour démontrer la création d'un index. Ouvrez un terminal dans la machine virtuelle LabEx. Vous pouvez utiliser le raccourci Xfce Terminal sur le bureau.

Connectez-vous au serveur MySQL en tant qu'utilisateur root :

mysql -u root -proot

Maintenant, créons la table users :

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Cette instruction SQL crée une table nommée users avec des colonnes pour id, username, email et created_at. La colonne id est définie comme clé primaire et s'incrémente automatiquement.

Insérons quelques données d'exemple dans la table users :

INSERT INTO users (username, email) VALUES
('john_doe', '[email protected]'),
('jane_smith', '[email protected]'),
('peter_jones', '[email protected]');

Créer un index sur une seule colonne

Maintenant, créons un index sur la colonne username. Cela aidera à accélérer les requêtes qui recherchent des utilisateurs par leur nom d'utilisateur.

CREATE INDEX idx_username ON users (username);

Cette instruction crée un index nommé idx_username sur la colonne username de la table users.

Vérifier l'index

Vous pouvez vérifier que l'index a été créé en utilisant la commande SHOW INDEXES :

SHOW INDEXES FROM users;

La sortie affichera les détails des index de la table users, y compris l'index idx_username que vous venez de créer. Vous devriez voir une ligne où Key_name est idx_username et Column_name est username.

+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name     | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY      |            1 | id          | A         |           3 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_username |            1 | username    | A         |           3 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Utiliser l'index

Pour voir l'avantage de l'index, vous pouvez utiliser la commande EXPLAIN pour analyser une requête qui utilise la colonne username. Nous aborderons EXPLAIN plus en détail à l'étape suivante, mais pour l'instant, regardons un exemple rapide.

EXPLAIN SELECT * FROM users WHERE username = 'john_doe';

La sortie de EXPLAIN montrera que la requête utilise l'index idx_username, ce qui signifie que la base de données peut trouver rapidement la ligne correspondante sans parcourir toute la table. Recherchez les colonnes possible_keys et key dans la sortie. Si l'index est utilisé, vous verrez idx_username dans ces colonnes.

Vous avez maintenant créé avec succès un index sur une seule colonne d'une table. Cela améliorera les performances des requêtes qui filtrent les données en fonction de la colonne indexée.

exit;

Analyser un plan de requête avec EXPLAIN

Dans cette étape, vous allez apprendre à utiliser l'instruction EXPLAIN en MySQL pour analyser le plan d'exécution d'une requête. Comprendre le plan de requête est essentiel pour identifier les goulots d'étranglement de performance et optimiser vos requêtes.

Qu'est-ce qu'un plan de requête ?

Un plan de requête est une feuille de route que le moteur de base de données utilise pour exécuter une requête. Il décrit l'ordre dans lequel les tables sont accédées, les index utilisés et les algorithmes appliqués pour récupérer les données. En analysant le plan de requête, vous pouvez comprendre comment la base de données exécute votre requête et identifier les domaines d'amélioration.

Utilisation de l'instruction EXPLAIN

L'instruction EXPLAIN fournit des informations sur la façon dont MySQL exécute une requête. Elle montre les tables impliquées, les index utilisés, l'ordre des jointures et d'autres détails qui peuvent vous aider à comprendre les performances de la requête.

Continuons à utiliser la table users que nous avons créée à l'étape précédente. Ouvrez un terminal dans la machine virtuelle LabEx (en utilisant le raccourci Xfce Terminal sur le bureau) et connectez-vous au serveur MySQL en tant qu'utilisateur root :

mysql -u root -proot

Maintenant, analysons une simple requête en utilisant EXPLAIN.

EXPLAIN SELECT * FROM users WHERE username = 'john_doe';

La sortie de l'instruction EXPLAIN sera une table avec plusieurs colonnes. Voici une explication de certaines des colonnes les plus importantes :

  • id : L'identifiant de l'instruction SELECT.
  • select_type : Le type de requête SELECT (par exemple, SIMPLE, PRIMARY, SUBQUERY).
  • table : La table qui est accédée.
  • type : Le type de jointure. C'est l'une des colonnes les plus importantes. Les valeurs courantes incluent :
    • system : La table n'a qu'une seule ligne.
    • const : La table a au plus une ligne correspondante, qui est lue au début de la requête.
    • eq_ref : Une ligne est lue de cette table pour chaque combinaison de lignes des tables précédentes. Cela est utilisé lors d'une jointure sur une colonne indexée.
    • ref : Toutes les lignes correspondantes sont lues de cette table pour chaque combinaison de lignes des tables précédentes. Cela est utilisé lors d'une jointure sur une colonne indexée.
    • range : Seules les lignes dans une plage donnée sont récupérées, en utilisant un index.
    • index : Un balayage complet de l'index est effectué.
    • ALL : Un balayage complet de la table est effectué. C'est le type le moins efficace.
  • possible_keys : Les index que MySQL pourrait utiliser pour trouver les lignes dans la table.
  • key : L'index que MySQL a réellement utilisé.
  • key_len : La longueur de la clé que MySQL a utilisée.
  • ref : Les colonnes ou les constantes qui sont comparées à l'index.
  • rows : Le nombre de lignes que MySQL estime devoir examiner pour exécuter la requête.
  • Extra : Informations supplémentaires sur la façon dont MySQL exécute la requête. Les valeurs courantes incluent :
    • Using index : La requête peut être satisfaite en utilisant uniquement l'index.
    • Using where : MySQL doit filtrer les lignes après avoir accédé à la table.
    • Using temporary : MySQL doit créer une table temporaire pour exécuter la requête.
    • Using filesort : MySQL doit trier les lignes après avoir accédé à la table.

Interprétation de la sortie de EXPLAIN

Pour la requête SELECT * FROM users WHERE username = 'john_doe', la sortie de EXPLAIN devrait ressembler à ceci :

+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+-------+-------+
| id | select_type | table | partitions | type | possible_keys | key          | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_username  | idx_username | 767     | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+

Dans cet exemple :

  • type est ref, ce qui signifie que MySQL utilise un index pour trouver la ligne correspondante.
  • possible_keys et key montrent tous les deux idx_username, ce qui signifie que MySQL utilise l'index idx_username que nous avons créé à l'étape précédente.
  • rows est 1, ce qui signifie que MySQL estime devoir examiner seulement une ligne pour exécuter la requête.

Analyser une requête sans index

Maintenant, analysons une requête qui n'utilise pas d'index. Tout d'abord, ajoutons une nouvelle colonne à la table users appelée city :

ALTER TABLE users ADD COLUMN city VARCHAR(255);

Maintenant, exécutons un EXPLAIN sur une requête qui recherche par city :

EXPLAIN SELECT * FROM users WHERE city = 'New York';

Puisque nous n'avons pas ajouté de données à la colonne city, mettons à jour l'une des lignes :

UPDATE users SET city = 'New York' WHERE username = 'john_doe';

Maintenant, exécutez à nouveau l'instruction EXPLAIN :

EXPLAIN SELECT * FROM users WHERE city = 'New York';

La sortie pourrait ressembler à ceci :

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | users | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

Dans cet exemple :

  • type est ALL, ce qui signifie que MySQL effectue un balayage complet de la table.
  • possible_keys et key sont tous les deux NULL, ce qui signifie que MySQL n'utilise aucun index.
  • rows est 3, ce qui signifie que MySQL estime devoir examiner toutes les 3 lignes de la table pour exécuter la requête.
  • Extra montre Using where, ce qui signifie que MySQL doit filtrer les lignes après avoir accédé à la table.

Cela indique que la requête n'est pas optimisée et pourrait bénéficier d'un index sur la colonne city.

exit;

Ajouter un index composite pour les requêtes multi-colonnes

Dans cette étape, vous allez apprendre à créer un index composite en MySQL. Un index composite est un index sur deux colonnes ou plus d'une table. Il peut améliorer considérablement les performances des requêtes qui filtrent les données en fonction de plusieurs colonnes.

Qu'est-ce qu'un index composite ?

Un index composite est un index qui couvre plusieurs colonnes. Il est utile lorsque les requêtes utilisent fréquemment plusieurs colonnes dans la clause WHERE. L'ordre des colonnes dans l'index composite est important. L'index est le plus efficace lorsque les colonnes sont spécifiées dans le même ordre dans la clause WHERE de la requête.

Continuons à utiliser la table users que nous avons créée dans les étapes précédentes. Ouvrez un terminal dans la machine virtuelle LabEx (en utilisant le raccourci Xfce Terminal sur le bureau) et connectez-vous au serveur MySQL en tant qu'utilisateur root :

mysql -u root -proot

Ajoutons plus de données à la table users, y compris différentes villes :

INSERT INTO users (username, email, city) VALUES
('alice_brown', '[email protected]', 'Los Angeles'),
('bob_davis', '[email protected]', 'Chicago'),
('charlie_wilson', '[email protected]', 'New York'),
('david_garcia', '[email protected]', 'Los Angeles');

Création d'un index composite

Supposons que vous exécutiez souvent des requêtes qui filtrent les utilisateurs à la fois par city et username. Dans ce cas, vous pouvez créer un index composite sur les colonnes city et username.

CREATE INDEX idx_city_username ON users (city, username);

Cette instruction crée un index nommé idx_city_username sur les colonnes city et username de la table users.

Vérification de l'index

Vous pouvez vérifier que l'index a été créé en utilisant la commande SHOW INDEXES :

SHOW INDEXES FROM users;

La sortie affichera les détails des index de la table users, y compris l'index idx_city_username que vous venez de créer. Vous devriez voir deux lignes pour idx_city_username, une pour la colonne city et une pour la colonne username.

+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY           |            1 | id          | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_username      |            1 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            1 | city        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            2 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Utilisation de l'index composite

Pour voir l'avantage de l'index composite, vous pouvez utiliser la commande EXPLAIN pour analyser une requête qui utilise à la fois les colonnes city et username dans la clause WHERE.

EXPLAIN SELECT * FROM users WHERE city = 'New York' AND username = 'charlie_wilson';

La sortie de EXPLAIN montrera que la requête utilise l'index idx_city_username, ce qui signifie que la base de données peut trouver rapidement la ligne correspondante sans parcourir toute la table. Recherchez les colonnes possible_keys et key dans la sortie. Si l'index est utilisé, vous verrez idx_city_username dans ces colonnes.

+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys     | key               | key_len | ref         | rows | filtered | Extra |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+
|  1 | SIMPLE      | users | NULL       | ref  | idx_city_username | idx_city_username | 770     | const,const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------+

Ordre des colonnes dans l'index

L'ordre des colonnes dans l'index composite est important. Si vous créez un index sur (username, city) au lieu de (city, username), l'index sera moins efficace pour les requêtes qui filtrent d'abord par city puis par username.

Par exemple, si nous avions un index sur (username, city) et que nous exécutons la requête suivante :

EXPLAIN SELECT * FROM users WHERE city = 'New York' AND username = 'charlie_wilson';

MySQL peut ne pas utiliser l'index, ou l'utiliser seulement partiellement, car la colonne city n'est pas la colonne principale de l'index.

exit;

Supprimer un index inutilisé

Dans cette étape, vous allez apprendre à supprimer un index inutilisé en MySQL. Bien que les index puissent améliorer considérablement les performances des requêtes, ils ajoutent également une surcharge aux opérations d'écriture (insertions, mises à jour et suppressions). Par conséquent, il est important d'identifier et de supprimer les index qui ne sont plus utilisés.

Pourquoi supprimer les index inutilisés ?

Les index inutilisés occupent de l'espace disque et peuvent ralentir les opérations d'écriture. Lorsque des données sont modifiées dans une table, le moteur de base de données doit également mettre à jour tous les index de cette table. Si un index n'est utilisé par aucune requête, il n'ajoute que des surcharges inutiles.

Continuons à utiliser la table users que nous avons créée dans les étapes précédentes. Ouvrez un terminal dans la machine virtuelle LabEx (en utilisant le raccourci Xfce Terminal sur le bureau) et connectez-vous au serveur MySQL en tant qu'utilisateur root :

mysql -u root -proot

Dans les étapes précédentes, nous avons créé un index nommé idx_username sur la colonne username. Supposons que, après avoir analysé vos modèles de requêtes, vous déterminiez que cet index n'est plus utilisé.

Suppression de l'index

Pour supprimer l'index idx_username, vous pouvez utiliser l'instruction DROP INDEX :

DROP INDEX idx_username ON users;

Cette instruction supprime l'index idx_username de la table users.

Vérification de la suppression de l'index

Vous pouvez vérifier que l'index a été supprimé en utilisant la commande SHOW INDEXES :

SHOW INDEXES FROM users;

La sortie affichera les détails des index de la table users. Vous ne devriez plus voir l'index idx_username dans la sortie.

+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name          | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| users |          0 | PRIMARY           |            1 | id          | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            1 | city        | A         |           3 |     NULL | NULL   | YES  | BTREE      |         |               | YES     | NULL       |
| users |          1 | idx_city_username |            2 | username    | A         |           7 |     NULL | NULL   |      | BTREE      |         |               | YES     | NULL       |
+-------+------------+-------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+

Identification des index inutilisés

Dans un scénario réel, identifier les index inutilisés peut être difficile. MySQL propose plusieurs outils et techniques pour vous aider dans cette tâche :

  • MySQL Enterprise Audit : Cette fonctionnalité vous permet de consigner toutes les requêtes exécutées sur votre serveur. Vous pouvez ensuite analyser les journaux de requêtes pour identifier quels index sont utilisés.
  • Performance Schema : La Performance Schema fournit des informations détaillées sur les performances du serveur, y compris l'utilisation des index.
  • Outils tiers : Plusieurs outils tiers peuvent vous aider à surveiller l'utilisation des index et à identifier les index inutilisés.

En surveillant régulièrement l'utilisation de vos index et en supprimant les index inutilisés, vous pouvez améliorer les performances globales de votre base de données.

exit;

Résumé

Dans ce laboratoire, vous avez appris à créer un index mono-colonne en MySQL pour améliorer les performances des requêtes, en particulier pour les tables volumineuses. Le processus a consisté à vous connecter au serveur MySQL, à créer une table users avec des colonnes pour id, username, email et created_at, et à insérer des données d'exemple.

L'étape clé a été de créer un index nommé idx_username sur la colonne username en utilisant l'instruction CREATE INDEX. Cet index accélérera les requêtes qui recherchent des utilisateurs par leur nom d'utilisateur, permettant à la base de données de localiser rapidement les lignes correspondant à des valeurs de nom d'utilisateur spécifiques sans parcourir toute la table.