本文由读者小平同志投稿,小平是一位非常朴实认真的猿,现于某上市证券公司做微服务开发,对 MySQL 优化有深入研究,小平的博客地址是https://blog.csdn.net/weixin_41193109。

MySQL的索引对查询速度的提高非常明显,但是索引种类很多,如复合索引、单列索引,那它们有什么区别和联系呢?下面我会对两者进行分析。

关键字

  • explain:MySQL查看执行计划的关键字,放在sql语句之前。

  • type:访问类型,表示找到所查询数据的方法,常见的有ref、range、index、all等。

  • keys:索引类型,表示MySQL此次查询中使用的索引,多个用逗号分开。

  • rows:遍历行数,表示MySQL此次查询遍历的行数大小,该值越小,查询速度会越快,是一个估计值,非绝对正确的。

准备工作

先来准备一张表和一点测试数据:

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`age` int(4) DEFAULT NULL,

`name` varchar(20) DEFAULT NULL,

`sex` int(3) DEFAULT NULL,

`nickname` varchar(30) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `testKey` (`name`,`age`,`nickname`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

INSERT INTO `user` VALUES ('1', '20', 'test1', '1', 'ntest1');

INSERT INTO `user` VALUES ('2', '21', 'test2', '0', 'ntest2');

INSERT INTO `user` VALUES ('3', '24', 'test1', '1', 'ntest3');

INSERT INTO `user` VALUES ('4', '23', 'test4', '0', 'ntest4');

INSERT INTO `user` VALUES ('5', '24', 'test5', '1', 'ntest5');

INSERT INTO `user` VALUES ('6', '25', 'test6', '0', 'ntest6');

单表复合索引

通过上面表格,我们会发现,复合索引( name, age, nickname)和它们三列的单个索引是有区别的(该案例不做复合索引和单列索引的性能分析)主要区别有以下几点:

  1. 复合索引中,只有最左边的一列单独使用才会触发索引,其他的列单个使用无法触发索引。

  2. 复合索引中,从最左边开始,相连的两个或多个会触发索引(相连和不相连的性能不同),如果没有最左边的列,后面的无论是否相连都不会触发索引。

  3. 通过分析我们可以发现,几个列的复合索引,就相当于 有几个索引,如复合索引( nameagenickname)相当于 name 索引、( name, age)索引以及( nameagenickname) 索引(注意,后面两个索引不能再按复合索引算,只是为了解释说明)。

  4. where 条件后面的顺序不影响复合索引的触发如 age=21andname='test1' 一样会触发复合索引(MySQL会对查询条件顺序进行优化,我们无需担心顺序问题,但是为了更好理解,建议合理安排顺序)。

单表复合索引的性能分析

上面表格中,第一行和第二行都走了索引,但是第一行是相连的两列,rows是1,这里我们可以说是使用了( nameage)索引(该索引并发真实存在,只是为了区分效果);第二行是不相连的两列rows是2,然后第四行是使用了复合索引的第一列 name 和非复合索引中的列作为查询条件,rows 同样是2,非相连的两列作为查询条件时,复合索引相当于使用了第一列作为查询条件。

为什么会这样呢?MySQL 在进行查询时,会根据索引筛选出复合索引的行,如果存在查询条件不在索引中的列,会进行二次筛选(即根据筛选出来的行进行二次查询),导致遍历的行数增加。

部分查询条件会导致全表扫描

特殊注意:

  1. 使用MySQL的CONCAT函数拼接条件一样会使用索引。

  2. 在使用 in 时,如果只有一个值,则等价于使用 =符号,会触发索引,包含两个或多个值,则索引失效。

  3. 在使用 not in 时,无论多少个值,索引都会失效。

  4. 使用 null 关键字查询时,无论值是否有为空的,都会触发索引。

  5. 在使用 like 关键字时,只要使用了%号进行模糊匹配,就会使索引失效。

  6. 网上说使用 is null 会使索引失效,我测试的结果是,使用 is null ,无论是复合索引还是单列索引都能触发索引。

总结

在我们使用单列索引和复合索引时,需要注意以下几点:

  1. 常用的字段放在第一列,经常和第一列一起使用的字段放在第二列,如用户表的电话和姓名,身份证表的身份照号和姓名,如果超过两列,则注意其顺序。

  2. 条件查询时,尽可能所有字段都有索引(如sex这种情况例外,因为sex的值只有三个,冗余性太高,定位比较差,不如全表检索快),这样能提高很多效率。

  3. 查询时避免会使索引失效的情况发生,如or条件,可以使用union或者union all来达到相同效果。

  4. 索引能提高查询效率,但是过多的索引,同样会降低我们的修改操作效率,对此,我们创建索引需要合理,在使用频率较低的情况下,尽量不要创建索引。

  5. select* 或许性能和指定字段相差不是非常大,但是代码的可读性降低了很多,不推荐使用。

关注牧码小子,后台回复 Java ,领取松哥为你精心准备的Java干货!

往期文章一览

1、工作之余,你是怎么提高技术的?

2、两年了,我写了这些干货!

3、想和大家谈一点合作

4、一个Java程序猿眼中的前后端分离以及Vue.js入门

5、跟着平台混了四年,现在要单飞了!

你点的每个在看,我都认真当成了喜欢

oracle查询两列合并成一列_MySQL复合索引和单列索引的单表查询分析相关推荐

  1. 如何将SQL查询出的两列合并成一列显示,并用逗号隔开

    如何将SQL查询出的两列合并成一列显示,并用逗号隔开 先给出一个表 DROP TABLE IF EXISTS `apps`; CREATE TABLE `apps` (`id` int NOT NUL ...

  2. pandas多列合并成一列

    前言 一入数据深似海,从此头发是路人.作为一个半路出家的学生,小弟当初是想做一名开发的,然而阴差阳错下,解除了数据分析这个工作,从此便爱上了这个让我秃头的行业(虚伪的说.) 数据分析有四个步骤,数据获 ...

  3. java怎么写合并列sql_SQL STUFF函数 拼接字符串 多列 合并成一列 转

    关于和并列的 要这种效果. create table tb(idint, value varchar(10)) insert into tbvalues(1,'aa') insert into tbv ...

  4. Oracle 将多列合并成一列

     对于下述表 create table reservation( reid varchar2(55) not null, rid varchar2(5), gid number(18), rtyp ...

  5. dataframe多列合并成一列

    DataFrame的几列数据合并成为一列 DataFrame的几列数据合并成为一列 1.1 方法归纳 1.2 .str.cat函数详解 1.2.1 语法格式: 1.2.2 参数说明: 1.2.3 核心 ...

  6. excel多列合并成一列加符号_Excel中如何将每行空格数据隔开为多列,以及如何合并多列数据为一列...

    投稿/科研合作:daixjdoctor@126.com 联系我们:137704924或372699348 群1-5:科研讨论.文献汇报群 网站:http://www.sleep-brain.com/ ...

  7. excel多列合并成一列加符号_Excel多列变(合并)一列的方法详解

    文章介绍两种excel多列变一列的方法来实现excel 多列合并一列的效果. 下图所示的excel多列变一列:将A:D列的数据变为F列的效果.如何实现这样的excel 多列合并一列呢?介绍两种exce ...

  8. mysql 优化表 3000万_mysql优化:专题三、关于单表查询,可以这么优化

    mysql优化:专题三.关于单表查询,可以这么优化 作者:PHPYuan 时间:2018-10-18 03:41:26 上篇讲解了「mysql优化专题」90%程序员都会忽略的增删改优化(2),相信大家 ...

  9. mysql数据库实验3查询_MySQL数据库实验:任务三 数据库的单表查询设计

    任务三 数据库的单表查询设计 文章目录任务三 数据库的单表查询设计[实训目的与要求][实训原理][实训步骤]一.简单查询二.按条件查询1.比较大小查询2.带in关键字的查询(确定集合)3.带BETWE ...

最新文章

  1. memcache基础教程
  2. Java 11 快要来了,编译 运行一个命令搞定!
  3. python输入123输出321_C语言编程:输出一个3位整数的逆序数,如输入123,输出321....
  4. 理解 Python 中的多线程
  5. Binlog同步工具Canal部署使用
  6. spring depends-on 不起作用
  7. 汇编语言(王爽)第四版检测点2.2答案
  8. js 对一个字段去重_js正则去重及(?=)的匹配规则
  9. 在 Mac 中 使用 Safari 常出现「此网页正使用大量内存...」如何修复?
  10. oracle重建spfile,Oracle修改spfile的位置
  11. 两种前端在线json编辑器方案(无法解决number精度丢失问题)
  12. 即席查询-Kylin
  13. 跟上Java8 - 日期和时间实用技巧,转自知乎王爵nice
  14. 更加精确的TCP Westwood拥塞控制算法
  15. debian9.6安装virtualbox
  16. Maven打包war报错
  17. Mysql基础篇(6)—— 视图
  18. 为PLOG增加了三套模板
  19. 【附源码】计算机毕业设计java裕民镇养老院信息管理系统设计与实现
  20. Mac_图片压缩_pngquant

热门文章

  1. C++ exception
  2. 初学Java Web(4)——Servlet学习总结
  3. 一张图搞定OAuth2.0
  4. 淘宝分布式调度框架TBSchedule
  5. LinkedList和ArrayList的区别
  6. 【前端开发系列】—— 文字阴影与样式
  7. 增大胸围!Mr Burning带你在家全方位虐胸!
  8. TeXworks使用教程指南
  9. 大数据哈希学习: 现状与趋势
  10. C#远程访问linux(ubuntu)或windows的mysql数据库