日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 组合索引 or_Mysql_组合索引和单列索引

發布時間:2023/11/30 数据库 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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_组合索引和单列索引的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。