初始化测试数据

创建一个测试用的表

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. HDU 6161.Big binary tree 二叉树

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  2. MySQL 导入导出数据

    导入数据 1. 使用 MySQl Workbench 界面操作 导入 csv JSON 格式文件 2 使用 load data 命令 load data 命令官网教程 https://dev.mysq ...

  3. oracle 查询clob 列时 很慢 , 未解决

    今天查询一张表 ,这张表有一个clob 列 select *  from  tableName :  很卡.. 难道是查询的太多? select * from tableName where rowN ...

  4. jsp页面的html代码显示不出来,提示Uncaught SyntaxError: Unexpected token <

    jsp页面的html代码显示不出来,提示Uncaught SyntaxError: Unexpected token < <input type="hidden" na ...

  5. Chapter5_初始化与清理_构造器初始化

    一.构造器初始化的基本顺序 在使用构造器进行初始化时,最需要注意的是初始化的顺序,这种方法可以给初始化的顺序带来很大的灵活性.看如下的一个例子. class Window{ Window(int ma ...

  6. Shell中的数组及其相关操作

    http://blog.csdn.net/jerry_1126/article/details/52027539 Shell中数据类型不多,比如说字符串,数字类型,数组.数组是其中比较重要的一种,其重 ...

  7. 20175316盛茂淞 2018-2019-2 《Java程序设计》第7周学习总结

    20175316盛茂淞 2018-2019-2 <Java程序设计>第7周学习总结 教材学习内容总结 第八章 常用实用类 一.String类 String类在java.lang包中,jav ...

  8. linux系统下部署DNS反向解析

    DNS服务概述 DNS(Domain Name System)域名系统,能够提供域名与IP地址的解析服务. 反向解析 反向解析是从IP地址到域名的解析过程.主要作用于服务器的身份验证. 部署反向解析 ...

  9. spring boot + vue + element-ui全栈开发入门

    今天想弄弄element-ui  然后就在网上找了个例子 感觉还是可以用的  第一步是完成了  果断 拿过来  放到我这里这  下面直接是连接  点进去 就可以用啊 本想着不用vue   直接导入连接 ...

  10. .net读取excel数据到DataSet中

    Dim objExcelFile As Excel.Application Dim objWorkBook As Excel.Workbook Dim objSheet As Excel.Worksh ...