初始化测试数据

创建一个测试用的表

create table dept(
id int primary key auto_increment ,
deptName varchar(32) not null unique,
salary decimal(12,6) not null,
remark varchar(256),
createDate date);

在表中插入一万条数据

BEGIN

Declare i int default 0;
while(i<=10000) do
begin
select i;
set i=i+1;
insert into dept(deptName,salary,createDate,remark) values(i,20000,now(),'test');
end ;
End while;
END

通过EXPLAIN分析SQL的执行计划

type:表示MySQL在表中找到所需行的方式,或者叫访问类型,常见类型如下(从左到右,性能由差到好)

ALL  index  range ref eq_ref  const,system  NULL

ALL: 全表扫描

index: 索引全扫描

range:索引范围扫描

ref:使用非唯一索引扫描

eq_ref:使用唯一索引扫描

const,system:单表中最多只有一个匹配行


以上:通过explain分析type是ALL 是性能最差的一种 以下:开始优化。

MySQL中BTREE索引的用法

普通的BTREE索引

优化前 explain select remark from dept where deptName = ?;  type ALL

增加索引 ALTER TABLE dept ADD INDEX index_remark (`remark`);

优化测试  explain select remark from dept where deptName = ?; type ref

联合BTREE索引

增加联合索引 ALTER TABLE dept ADD INDEX index_all (`deptName`,`remark`,`createDate`);

explain select deptName,remark,createDate from dept where deptName='2' and remark = 'test'and createDate ='2018-07-22'; type ref

但是explain select deptName,remark,createDate from dept where remark = 'test'and createDate ='2018-07-22'; type index

 ——type从ref(使用非唯一索引扫描)变成了index(索引全扫描),

上面两个SQL 索引相同 Type不同是因为 BTREE索引中匹配最左前缀 比如给col1+col2+col3字段上加联合索引能够被包含

col1+col2 、col1+col2+col3、col1+col3使用(顺序没有影响 比如 where col1=? and col2=? 和 where col2=? and col1=? 结果一样)

使用联合索引 相当于一下子创建了如上的三个索引,这就是联合索引的好处

存在索引但不能使用索引的经典场景

例句:explain select deptName,remark,createDate from dept where deptName='2' and remark = 'test'and createDate ='2018-07-22'; type ref

下面是反面教材:

1.以%开头的LIKE查询不能使用BTREE索引

explain select deptName,remark,createDate from dept where deptName like'%2' and remark = 'test'and createDate ='2018-07-22'; type index

2.数据类型出现隐式转换时也不能使用索引

explain select deptName,remark,createDate from dept where deptName =2 and remark = 'test'and createDate ='2018-07-22'; type index

3.复合索引时 不符合最左匹配原则(上面已经提到)

explain select deptName,remark,createDate from dept where remark = 'test'and createDate ='2018-07-22'; type index

4.用or分隔开的条件,如果or前的条件中的列有索引,后面的列中没有索引,那么涉及到的索引都不会使用到

explain select deptName,remark,createDate from dept where deptName ='2' and remark = 'test'and createDate ='2018-07-22' or salary =200; type ALL

Order By语句

  order by 字段混合使用DESC ASC 不会使用索引

    select * from table order by key1 desc,key2 asc (尽量不要出现这种混合排序)

  Where条件过滤的关键字和Order by中所使用的不同 不会使用索引

    select * from table where key2 = ? order by key1 (order by 出现的关键字 尽量 在where条件中也出现)

优化Group By语句

  当我们的SQL语句需要Group By分组时:

  explain分析SQL的时候 Extra那一列有时候会出现 using Filesort表示需要额外的排序  如果业务没有要求排序 我们可以通过禁止排序, 加上 Order By NULL 有时候可以去掉using filesort

MySQL应不应该加唯一约束和外键约束

外键约束可以通过代码控制,加起来开发很不方便不建议加。如果业务需要唯一约束,因为唯一约束代码很难控制,必须加

对于唯一约束,有人说先查出来数据库已经存在的 再去判断传值存不存在。这样的缺点 1.查询所有已经存在的很费时间,2.需要考虑并发 不然重复数据还是会进入到数据库

一旦进入了错误数据 以后想加唯一约束都加不上了

查询语句关键字使用顺序: WHERE  GROUP BY HAVING ORDER BY  DESC LIMIT

补充

唯一索引

explain select deptName,remark,createDate from dept where id=2; type const 像这种利用唯一索引做where条件的效率最高(主键默认被加上了唯一索引)

SQL表连接查询时 表连接的条件(也就是外键)必须加索引(阿里巴巴代码规范看到的)

重要: 多表连接的时候 join on(a.id=b.id2) 连接外键id、id2 必须加索引。MySQL规定作为外键的字段必须有索引 也是为了让我们表连接的时候 用到索引(其实做到这点 基本上足够优化百分之八十的SQL了)

MySQL如何使用索引的更多相关文章

  1. MySQL引擎、索引和优化(li)

    一.存储引擎 存储引擎,MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术 ...

  2. MySQL的InnoDB索引原理详解

    摘要 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本篇 ...

  3. MySQL和Lucene索引对比分析

    MySQL和Lucene都可以对数据构建索引并通过索引查询数据,一个是关系型数据库,一个是构建搜索引擎(Solr.ElasticSearch)的核心类库.两者的索引(index)有什么区别呢?以前写过 ...

  4. MySQL(五) MySQL中的索引详讲

    序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...

  5. mysql优化之索引篇

    对mysql优化是一个综合性的技术,主要包括 a: 表的设计合理化(符合3NF) b: 添加适当索引(index) [四种: 普通索引.主键索引.唯一索引unique.全文索引] c: 分表技术(水平 ...

  6. MySQL的InnoDB索引原理详解 (转)

    摘要: 本篇介绍下Mysql的InnoDB索引相关知识,从各种树到索引原理到存储的细节. InnoDB是Mysql的默认存储引擎(Mysql5.5.5之前是MyISAM,文档).本着高效学习的目的,本 ...

  7. Mysql 复合键索引性能

    数据库的常见的索引一般是单个字段,如果多个字段的组合,那么就组成了复合索引.对于组合索引,如果 对其中一字段做为条件查询,会出现什么情况呢? 一.例子 mysql> show create ta ...

  8. Mysql几种索引类型的区别及适用情况

    如大家所知道的,Mysql目前主要有以下几种索引类型:FULLTEXT,HASH,BTREE,RTREE. 那么,这几种索引有什么功能和性能上的不同呢? FULLTEXT 即为全文索引,目前只有MyI ...

  9. mysql 强制走索引

    查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...

  10. Mysql数据库的索引原理

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

随机推荐

  1. jQuery on() 方法 为选定已存在元素和未来元素绑定标准事件和自定义事件

    很有必要说说jQuery的on方法,这个方法存在大乾坤大奥秘,主要注意两点: 1.为已存在元素和未来元素(动态添加元素)绑定处理函数. 2.自定义一个非标准的事件并绑定处理函数. 定义和用法 on() ...

  2. 关于CDN与缓存(浏览器和CDN)

    本文目录:一.引入 二.CDN定义 三.关于缓存 四.浏览器缓存 一.引入 客户端直接从源站点获取数据,当服务器访问量大时会影响访问速度,进而影响用户体验,且无法保证客户端与源站点间的距离足够短,适合 ...

  3. arr.sort()

    var ary = [12,2,0,15,32,125,52,63,45,24]; /* * sort实现原理 每一次拿出数组中的当前项和后一项,每一次这样的操作都会让传递的匿名函数执行一次,不仅执行 ...

  4. mac 下 tomcat7的安装

    1.到 apache官方主页 下载 tomcat7 版本的完整 tar.gz 安装包 解压拷贝到 /Library目录下,并命名为Tomcat.   2.修改目录权限,终端输入 sudo chmod ...

  5. 如何选择合适的PHP版本

    PHP版本很多,包括32位64位以及线程安全与非线程安全在内的php版本多达几百个,应该如何选择PHP版本呢 PHP32和64的选择和区别 32bit的php的整型数据最大最小正负2GB左右(0x7F ...

  6. 使用signalr实现网页和微信公众号实时聊天(上)

    最近项目中需要实现客户在公众号中和客服(客服使用后台网站系统)进行实时聊天的功能.折腾了一段时间,实现了这个功能.现在将过程记录下,以便有相同需求的同行可以参考,也是自己做个总结.这篇是上,用手机编辑 ...

  7. HDU-4763 Theme Section KMP

    题意:求最长的子串E,使母串满足EAEBE的形式,A.B可以任意,并且不能重叠. 题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4763 思 ...

  8. 用STS构建spring boot

    操作步骤:1. 登录地址http://spring.io/tools 下载sts,spring-tool-suite-3.9.5.RELEASE-e4.8.0-win32-x86_64.zip2. 解 ...

  9. SAS 循环与数组

    SAS 循环与数组 SAS提供了循环语句以满足在编程中需要多次执行相同操作的情 况.有时还需要对不同的变量执行相同的操作,此时可定义SAS数组,并通过数组名和下标来引用这些变量. 1 循环 SAS循环 ...

  10. Win10专业版激活

    转载来自:http://www.zhuangjiba.com/bios/3432.html 如何激活win10正式版图文解说 打开开始菜单,找到设置,点开“更新和安全”,切换到“激活”选项卡,查看到当 ...