Maison  >  Article  >  base de données  >  Fusion d'index mysql : un SQL peut utiliser plusieurs index

Fusion d'index mysql : un SQL peut utiliser plusieurs index

黄舟
黄舟original
2017-02-21 10:15:434860parcourir

Veuillez indiquer la source de la réimpression : fusion d'index mysql : un sql peut utiliser plusieurs index

Avant-propos

La fusion d'index de MySQL n'est pas une nouvelle fonctionnalité. Il a été implémenté dès la version mysql5.0. La raison pour laquelle j'écris encore ce billet de blog est que de nombreuses personnes croient encore à tort qu'une instruction SQL ne peut utiliser qu'un seul index. Cet article illustrera comment utiliser la fusion d'index à travers quelques exemples.

Qu'est-ce que la fusion d'index

Jetons un coup d'œil à la description de la fusion d'index dans le document mysql :

The Index Merge method is used to retrieve rows with several range scans and to merge their results into one. 
The merge can produce unions, intersections, or unions-of-intersections of its underlying scans. 
This access method merges index scans from a single table; 
it does not merge scans across multiple tables.

1 La fusion d'index consiste à fusionner les analyses de plage de plusieurs index en un seul index.
2. Lors de la fusion d'index, les index seront d'abord combinés, croisés ou intersectés, puis combinés pour fusionner en un seul index.
3. Les index qui doivent être fusionnés ne peuvent appartenir qu'à une seule table. La fusion d'index ne peut pas être effectuée sur plusieurs tables.

Quels sont les avantages de l'utilisation de la fusion d'index

En termes simples, la fusion d'index permet à un SQL d'utiliser plusieurs index. Prenez d'abord l'intersection, l'union ou l'intersection, puis l'union de ces indices. Cela réduit le nombre de fois où il faut récupérer des données de la table de données et améliore l'efficacité des requêtes.

Comment confirmer que la fusion d'index est utilisée

Lors de l'utilisation d'explication pour exécuter une instruction SQL, si la fusion d'index est utilisée, index_merge sera affiché dans la colonne type du contenu de sortie et tous les index utilisés seront affichés dans la colonne clé. Comme suit :
Fusion dindex mysql : un SQL peut utiliser plusieurs index

Il existe les types suivants dans le champ supplémentaire d'explication :
Utiliser l'index d'union pour obtenir l'union
Utiliser sort_union pour trier d'abord les données récupérées par rowid, puis obtenir l'union
Utiliser intersect pour obtenir l'intersection

Vous constaterez qu'il n'y a pas de sort_intersect, car selon l'implémentation actuelle, si vous souhaitez récupérer l'intersection par index, vous devez vous assurer que l'ordre des données récupérées via l'index est cohérent avec l'ordre des rowid. Il n’est donc pas nécessaire de trier.

Exemple de fusion d'index sort_union

Structure du tableau de données

1

2

3

4

5

6

7

8

9

10

11

12

13

14

mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1_part1` int(11) NOT NULL DEFAULT '0',
  `key1_part2` int(11) NOT NULL DEFAULT '0',
  `key2_part1` int(11) NOT NULL DEFAULT '0',
  `key2_part2` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `key1` (`key1_part1`,`key1_part2`),
  KEY `key2` (`key2_part1`,`key2_part2`)
) ENGINE=MyISAM AUTO_INCREMENT=18 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Données

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

mysql> select * from test;
+----+------------+------------+------------+------------+
| id | key1_part1 | key1_part2 | key2_part1 | key2_part2 |
+----+------------+------------+------------+------------+
|  1 |          1 |          1 |          1 |          1 |
|  2 |          1 |          1 |          2 |          1 |
|  3 |          1 |          1 |          2 |          2 |
|  4 |          1 |          1 |          3 |          2 |
|  5 |          1 |          1 |          3 |          3 |
|  6 |          1 |          1 |          4 |          3 |
|  7 |          1 |          1 |          4 |          4 |
|  8 |          1 |          1 |          5 |          4 |
|  9 |          1 |          1 |          5 |          5 |
| 10 |          2 |          1 |          1 |          1 |
| 11 |          2 |          2 |          1 |          1 |
| 12 |          3 |          2 |          1 |          1 |
| 13 |          3 |          3 |          1 |          1 |
| 14 |          4 |          3 |          1 |          1 |
| 15 |          4 |          4 |          1 |          1 |
| 16 |          5 |          4 |          1 |          1 |
| 17 |          5 |          5 |          1 |          1 |
| 18 |          5 |          5 |          3 |          3 |
| 19 |          5 |          5 |          3 |          1 |
| 20 |          5 |          5 |          3 |          2 |
| 21 |          5 |          5 |          3 |          4 |
| 22 |          6 |          6 |          3 |          3 |
| 23 |          6 |          6 |          3 |          4 |
| 24 |          6 |          6 |          3 |          5 |
| 25 |          6 |          6 |          3 |          6 |
| 26 |          6 |          6 |          3 |          7 |
| 27 |          1 |          1 |          3 |          6 |
| 28 |          1 |          2 |          3 |          6 |
| 29 |          1 |          3 |          3 |          6 |
+----+------------+------------+------------+------------+
29 rows in set (0.00 sec)

使用索引合并的案例

1

2

3

4

5

6

7

8

9

10

11

12

13

mysql> explain select * from test where (key1_part1=4 and key1_part2=4) or (key2_part1=4 and key2_part2=4)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: index_merge
possible_keys: key1,key2
          key: key1,key2
      key_len: 8,4
          ref: NULL
         rows: 3
        Extra: Using sort_union(key1,key2); Using where
1 row in set (0.00 sec)

未使用索引合并的案例

1

2

3

4

5

6

7

8

9

10

11

12

13

mysql> explain select * from test where (key1_part1=1 and key1_part2=1) or key2_part1=4\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: ALL
possible_keys: key1,key2
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 29
        Extra: Using where
1 row in set (0.00 sec)

résumé sort_union

À partir des deux cas ci-dessus, vous pouvez constater que les instructions SQL du même mode peuvent parfois utiliser des index, et parfois ne pas pouvoir utiliser d'index. La possibilité d'utiliser l'index dépend du fait que l'optimiseur de requêtes MySQL pense que l'utilisation de l'index est plus rapide après avoir analysé les données statistiques.
Par conséquent, discuter simplement de la question de savoir si une instruction SQL peut utiliser des index est un peu unilatéral, et les données doivent également être prises en compte.

Cas d'utilisation de la fusion d'index syndicaux

Structure du tableau de données

1

2

3

4

5

6

7

8

9

10

11

12

13

14

mysql> show create table test\G
*************************** 1. row ***************************
       Table: test
Create Table: CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `key1_part1` int(11) NOT NULL DEFAULT '0',
  `key1_part2` int(11) NOT NULL DEFAULT '0',
  `key2_part1` int(11) NOT NULL DEFAULT '0',
  `key2_part2` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `key1` (`key1_part1`,`key1_part2`,`id`),
  KEY `key2` (`key2_part1`,`key2_part2`,`id`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

数据结构和之前有所调整。主要调整有如下两方面:
1、引擎从myisam改为了innodb。
2、组合索引中增加了id,并把id放在最后。

数据

数据和上面的数据一样。

使用索引合并的案例

1

2

3

4

5

6

7

8

9

10

11

12

13

mysql> explain select * from test where (key1_part1=4 and key1_part2=4) or (key2_part1=4 and key2_part2=4)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: index_merge
possible_keys: key1,key2
          key: key1,key2
      key_len: 8,8
          ref: NULL
         rows: 2
        Extra: Using union(key1,key2); Using where
1 row in set (0.00 sec)

résumé syndical

Les mêmes données, la même instruction SQL, mais la structure de la table de données a été ajustée, de sort_union à union. Il y a plusieurs raisons :
1. Tant que les données récupérées via l'index ont été triées par rowid, l'union peut être utilisée.
2. Ajoutez le champ id à la fin de l'index combiné. Le but est de trier les données récupérées par les deux premiers champs de l'index par identifiant.
3. Changez le moteur de myisam en innodb Le but est de rendre l'ordre de l'id et du rowid cohérent.

cas d'utilisation d'intersection

fusion d'index mysql : un sql peut utiliser plusieurs index
http://www.php.cn/

Ce qui précède est la fusion d'index mysql :Un SQL peut utiliser le contenu de plusieurs index. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn