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进行查找 .

转载来源:传送门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql与mangodb多租户_MongoDB多租户(Java):如何使用MongoClient在运行时切换具有不同数据库凭据的MongoDB数据库?...

我正面临一个关于MongoDB多租户的问题.我有两个不同的mongoDB数据库(db1和db2).这两者都有不同的凭据.db1凭据:userName:admin密码:passwddb2凭据:userName:admin1密码:passwd1我需要在运行时从一个数据库切…

python 库 全局变量_python局部变量和全局变量global

当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的。这称为变量的 作用域 。所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。使用局部变量例7.3 使用局部…

java 自省_自知 自省 自立 自信 自尊 自治 自强 自制

自知 自省 自立 自信 自尊 自治 自强 自制能知人者有智力,能自知才是真正的智者;能战胜别人者有力量,能战胜自己才是真正的强者;能知足者就是富有,能勤奋顽强坚持才是真正的有志者;不失其立足之地的人可以长…

java中json重复数据结构_JAVA把各种数据结构转换为JSON格式

Java代码import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import net.sf…

字节字符区别Java_【JAVA基础】字符数组与字节数组的区别

String.getBytes()和String.tocharArray(),字节数组和字符数组的区别String.getBytes()是将字符串转化为一个字节数组。而String.toCharArray()是将一个字符串转化为一个字符数组。【例如】byte bys[] “国庆60周年”.getBytes();char chs[]“国庆60周年”.toCharAr…

mysql日志管理_关于MySQL的日志管理(binlog)

关于MySQL的日志管理(binlog)一、查看binlog的启用状态最常用的mysql版本是5.7,默认不开启binlog,可以在登录mysql之后,利用以下命令查看当前的binlog启用状态:mysql show variables like "%log_bin%";图中显示“ON”&a…

java精确测量文本高度_基于文本精确计算UITableViewCell的高度

我正在开发一个ios应用程序,并使用autolayout我正在尝试创建一个具有不同行高的表视图 .原型单元的布局如下:我有一个主单元格(黑色)里面有一个UIView(红色),里面有一个UILabel(蓝色)我添加的Autolayout约束如图所示:The UIView h…

php做一个微信退款,PHP实现微信退款功能

大家好,我是小编,最近在调微信退款接口,发现有许多坑,更大家分享一下① 要是在测试的时候,网页提示 curl 58 说明 证书的路径出现问题(这里要填物理路径,也就是绝对路径)②网页提示curl 52 说明你的证书引入…

php显示时间,php实现用已经过去多长时间的方式显示时间

本文实例讲述了php用已经过去多长时间的方式显示时间的方法。分享给大家供大家参考。具体如下:这里以一种可读性比较好的方式显示已经过去多长时间,比如:距离现在10秒,距离现在1天等等。function time_is_older_than($t, $check_t…

java中日期计算时间差,java中依据,两个日期,计算时间差

java中根据,两个日期,计算时间差。分别获取两个时间的毫秒数Date.getTime(),相减,得到的值/1000为秒数,/60*1000为分钟数,/60*60*1000为小时数。/*** 计算时间差** param begin* param end* return*/public…

php获取token失败,微信开发,老是获取token失败

微信开发,总是获取token失败$appid wx1aabc8673b8f103a;$appsecret 9aa99fc9db9bf1321c1afe05feb29b6c;$url "https://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credential&appid$appid&secret$appsecret";$urlhttps://api.weixin.…

2008下php上传文件崩溃,php – 当用户反复尝试上传无效文件类型时,网站崩溃

我试图理解错误……我有一个允许用户上传CSV的网络应用程序.如果文件类型不是CSV,则不会发生任何操作,页面只显示“无效的文件类型”.如果用户尝试上载无效的文件类型并反复单击触发处理上载的PHP文件的按钮,则PHP文件最终会无响应,并且网站崩溃时出现以下错误:&quo…

java错误1601解决方法,求助解决错误

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1610)at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1590)at …

java == hashcode,java中==和equals和hashCode的区别

java中和equals和hashCode的区别 的作用:基本类型:比较的就是值是否相同引用类型:比较的就是地址值是否相同(确切的说,是堆内存地址)equals 的作用:引用类型:默认情况下,比较的是地址值。public boolean eq…

java经典设计模式4,JAVA设计模式(4) 之装饰设计模式

在现实生活中我们的汽车都具备跑的功能,我们可以不改变汽车原有功能的前提下,把它放入一个装修厂,开进去让里面给咱们的车子做一些装饰,开出来之后呢,就具备了上天的功能了(技术可达是可以的哈),这就给原来…

java读取gxk文件,Java中常见的IO流及其使用

Java中IO流分成两大类,一种是输入流,所有的输入流都直接或间接继承自InputStream抽象类,输入流作为数据的来源,我们可以通过输入流的read方法读取字节数据;另一种是输出流,所有的输出流都直接或间接继承自O…

matlab+voronoin函数,在Voronoi区域中生成随机点,并创建具有高维数据的Voronoi区域...

我正在使用k-means聚类算法,并且对于每个聚类质心,我试图为质心生成n维Voronoi区域 . 之后我需要从Voronoi区域生成随机点 .我已经尝试使用Matlab / Octave和scipy来获得n维Voronoi区域 . 但我有两个问题 .生成顶点和区域后,如何从区域生成随…

matlab双纵轴刻度覆盖问题,求助: matlab双纵轴换图问题

非常感谢!不过,y2的范围是-1*(10^6),7*(10^6),但是不等分:(把y1的范围调成0.4:0.2:5.8也有28个元素,然后y2也有28个元素,但是不等分,是个曲线,而且,这个曲线的值与y1是有关的。数据见附件syms d…

php最新图片漏洞,2018最新PHP漏洞利用技巧

本文学习了几种新式的php exploit方法,在此做一笔记文件删除漏洞, unlink()Phar 反序列化, file*()PHP对象实例化, ReflectionClass()0x01 WordPress Design Flaw Leads to WooCommerce RCEWooCommerce 3.4.6本版本之前存在任意删除漏洞,因为WordPress的…

php v-for=,Vue中v-for循环节点的实现代码

本篇文章给大家带来的内容是关于Vue中v-for循环节点的实现代码,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。Title父循环第一次子循环第一次json数据的第几条数值{{index}}{{indo}}{{bp.index}}{{bp.childName}}let ernew …