mysql 组合索引 or_Mysql_组合索引和单列索引
一、目標
什么時候使用組合索引,什么時候使用單獨索引
組合索引、單獨索引區別
組合索引:最左前綴匹配原則
二、前期數據準備
1. 建表
CREATE TABLE `user` (
`uid`int(11) NOT NULLAUTO_INCREMENT,
`name`varchar(50) DEFAULT NULL,
`pwd`varchar(50) DEFAULT NULL,
`create_time`datetime DEFAULT NULL,
`modify_time`timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`rids`varchar(15) DEFAULT NULL,
`nickname`varchar(45) DEFAULT NULL,
`company`varchar(15) DEFAULT NULL,PRIMARY KEY(`uid`),UNIQUE KEY`name_UNIQUE` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
2.插入數據
INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (1, 'rocker', 'rocker', NULL, '2019-10-08 11:05:02', '1', 'rocker', 'rocker');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (2, 'danny', 'danny', NULL, '2019-10-08 11:31:36', '2', 'rocker', 'danny');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (3, 'tom', 'tom', NULL, '2019-10-08 11:31:39', '1', 'tom', 'rocker');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (4, 'messi', 'messi', NULL, '2019-10-08 11:31:21', '2', 'messi', 'messi');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (5, 'wenger', 'wenger', NULL, '2019-10-08 11:29:38', '1', 'wenger', 'rocker');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (6, 'henry', 'henry', NULL, '2019-10-08 11:30:46', '2', 'henry', 'henry');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (7, 'ronaldo', 'ronaldo', NULL, '2019-10-08 11:30:49', '1', 'ronaldo', 'ronaldo');INSERT INTO `monitor`.`user`(`uid`, `name`, `pwd`, `create_time`, `modify_time`, `rids`, `nickname`, `company`) VALUES (8, 'kaka', 'kaka', NULL, '2019-10-08 11:29:45', '2', 'kaka', 'rocker');
三、分析索引區別
1.不加索引
首先在'nickname'和‘company’這倆字段不加索引的情況下執行一個查詢語句,并分析(explain詳解:傳送門)
mysql> explain select * from user where nickname = 'rocker' and company = 'rocker';+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 12.50 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
可以看到,沒有走索引,總共查詢了8條數據,而表中總共也是8條數據,相當于全表掃描了。
mysql> explain select * from user where company = 'rocker' or nickname = 'rocker';+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 23.44 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
可以看到:
不加任何索引的情況下,不管是and還是or,都是全表掃描,沒有索引。
2.單獨索引
給nickname和company分別加上索引,再執行and和or的sql查詢
alter table user add index`idx_nickname` (`nickname`);alter table user add index `idx_company` (`company`);
執行查詢語句and
mysql> explain select * from user where nickname = 'rocker' and company = 'rocker';+----+-------------+-------+------+--------------------------+--------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+--------------------------+--------------+---------+-------+------+-------------+
| 1 | SIMPLE | user | ref | idx_nickname,idx_company | idx_nickname | 138 | const | 2 | Using where |
+----+-------------+-------+------+--------------------------+--------------+---------+-------+------+-------------+
1 row in set (0.05 sec)
執行查詢語句or
mysql> explain select * from user where company = 'rocker' or nickname = 'rocker';+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| 1 | SIMPLE | user | ALL | idx_composition | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
可以看到:
加上索引后and查詢是可以走索引的,但是只有一個索引起作用,對于另一個索引字段還是要進行遍歷,而且and查詢會根據關聯性高(符合該條件的行數少)選擇具體走哪個索引
or查詢不走索引
3.組合索引
刪除原先的單獨索引,新增組合索引
alter table user drop index`idx_nickname`alter table user drop index`idx_company`alter table user add index `idx_composition` (`nickname`,`company`);
執行查詢語句and
mysql> explain select * from user where nickname = 'rocker' and company = 'rocker';+----+-------------+-------+------+-----------------+-----------------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------------+------+-------------+
| 1 | SIMPLE | user | ref | idx_composition | idx_composition | 186 | const,const | 1 | Using where |
+----+-------------+-------+------+-----------------+-----------------+---------+-------------+------+-------------+
1 row in set (0.00 sec)
執行查詢語句or
mysql> explain select * from user where company = 'rocker' or nickname = 'rocker';+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
| 1 | SIMPLE | user | ALL | idx_composition | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+-----------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
可以看到:
加上組合索引后,組合索引起作用,只需查詢一條符合結果的數據,效率要比單獨索引高
復合索引對于or查詢不起作用
4.組合索引查詢單個索引列
對于組合索引為(nickname,company)這個順序的情況,與上面的情況順序調換
alter table user drop index`idx_composition`;alter table user add index `idx_composition` (`company`,`nickname`);
mysql> explain select * from user where nickname = 'rocker';+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| 1 | SIMPLE | user | ref | idx_composition | idx_composition | 138 | const | 2 | Using where |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
1 row in set (0.00sec)
mysql> explain select * from user where company = 'rocker';+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
可以看到:
組合索引中nickname在前時,單獨查詢nickname會走索引,單獨查詢compamy不會走索引
對于組合索引為(company,nickname)這個順序的情況
alter table user drop index`idx_composition`;alter table user add index `idx_composition` (`company`,`nickname`);
mysql> explain select * from user where nickname = 'rocker';+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00sec)
mysql> explain select * from user where company = 'rocker';+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
| 1 | SIMPLE | user | ref | idx_composition | idx_composition | 48 | const | 2 | Using where |
+----+-------------+-------+------+-----------------+-----------------+---------+-------+------+-------------+
1 row in set (0.00 sec)
可以看到:
組合索引中compamy在前時,單獨查詢compamy會走索引,單獨查詢nickname不會走索引
為什么會出現這個情況呢?
對于復合索引:Mysql從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 可以支持 |a |? a,b |? a,b,c | 3種組合進行查找,但不支持 b,c進行查找 .
轉載來源:傳送門
總結
以上是生活随笔為你收集整理的mysql 组合索引 or_Mysql_组合索引和单列索引的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 青春进行时剧情介绍
- 下一篇: 成都大熊猫繁育基地残疾人要门票吗