Maison > Article > base de données > Fusion d'index mysql : un SQL peut utiliser plusieurs index
Veuillez indiquer la source de la réimpression : fusion d'index mysql : un sql peut utiliser plusieurs index
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.
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.
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.
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 :
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.
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) |
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) |
À 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.
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) |
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.
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) !