建表SQL

CREATE TABLE staffs (
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR (24) NULL DEFAULT '' COMMENT '姓名',
age INT NOT NULL DEFAULT 0 COMMENT '年龄',
pos VARCHAR (20) NOT NULL DEFAULT '' COMMENT '职位',
add_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时间'
) CHARSET utf8 COMMENT '员工记录表' ; INSERT INTO staffs(NAME,age,pos,add_time) VALUES('z3',22,'manager',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('July',23,'dev',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('2000',23,'dev',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES(null,23,'dev',NOW());
SELECT * FROM staffs; ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(name, age, pos);

案例(索引失效)

1、全值匹配我最爱

索引  idx_staffs_nameAgePos 建立索引时 以 name , age ,pos 的顺序建立的。全值匹配表示 按顺序匹配的
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July';
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25;
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = 'dev';

说明:如果查询过程中,若没有查询第一个NAME字段,索引将无效

有NAME,无age,部分索引失效

第一个索引字段相当于火车头,后面的索引字段相当于车厢,如果只剩下车头,火车依然可以开动,若没有车头,火车将无法运行。可以以此进行类比。

2、最佳左前缀法则

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。

and 忽略左右关系。既即使没有没有按顺序 由于优化器的存在,会自动优化。
经过试验结论 建立了 idx_nameAge 索引 id 为主键
1.当使用覆盖索引的方式时,(select name/age/id from staffs where age=10 (后面没有其他没有索引的字段条件)),即使不是以 name 开头,也会使用 idx_nameAge 索引。
既 select 后的字段 有索引,where 后的字段也有索引,则无关执行顺序。
2.除开上述条件 才满足最左前缀法则。 EXPLAIN SELECT * FROM staffs WHERE age = 25 AND pos = 'dev'; EXPLAIN SELECT * FROM staffs WHERE pos = 'dev';

口诀:带头大哥不能死,中间兄弟不能断。百分like加右边

3、不要在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描

EXPLAIN SELECT * FROM staffs WHERE left(NAME,4) = 'July';

4、存储引擎不能使用索引中范围条件右边的列

范围 若有索引则能使用到索引,范围条件右边的索引会失效(范围条件右边与范围条件使用的同一个组合索引,右边的才会失效。若是不同索引则不会失效)

5、尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *

6、mysql 在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描

索引  idx_nameAgeJob
idx_name
使用 != 和 <> 的字段索引失效( != 针对数值类型。 <> 针对字符类型
前提 where and 后的字段在混合索引中的位置比比当前字段靠后 where age != 10 and name='xxx' ,这种情况下,mysql自动优化,将 name='xxx' 放在 age !=10 之前,name 依然能使用索引。只是 age 的索引失效)

7、is not null 也无法使用索引,但是is null是可以使用索引的

8、like以通配符开头('%abc...')mysql索引失效会变成全表扫描的操作

like ‘%abc%’ type 类型会变成 all
like ‘abc%’ type 类型为 range ,算是范围,可以使用索引

问题:解决like '%字符串%'时索引不被使用的方法??

建表,插入数据

CREATE TABLE `tbl_user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(20) DEFAULT NULL,
`age` INT(11) DEFAULT NULL,
email VARCHAR(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; #drop table tbl_user INSERT INTO tbl_user(NAME,age,email) VALUES('1aa1',21,'b@163.com');
INSERT INTO tbl_user(NAME,age,email) VALUES('2aa2',222,'a@163.com');
INSERT INTO tbl_user(NAME,age,email) VALUES('3aa3',265,'c@163.com');
INSERT INTO tbl_user(NAME,age,email) VALUES('4aa4',21,'d@163.com');
INSERT INTO tbl_user(NAME,age,email) VALUES('aa',121,'e@163.com');

建索引之前进行测试

#before index

EXPLAIN SELECT NAME,age    FROM tbl_user WHERE NAME LIKE '%aa%';

EXPLAIN SELECT id    FROM tbl_user WHERE NAME LIKE '%aa%';
EXPLAIN SELECT NAME FROM tbl_user WHERE NAME LIKE '%aa%';
EXPLAIN SELECT age FROM tbl_user WHERE NAME LIKE '%aa%'; EXPLAIN SELECT id,NAME FROM tbl_user WHERE NAME LIKE '%aa%';
EXPLAIN SELECT id,NAME,age FROM tbl_user WHERE NAME LIKE '%aa%';
EXPLAIN SELECT NAME,age FROM tbl_user WHERE NAME LIKE '%aa%'; EXPLAIN SELECT * FROM tbl_user WHERE NAME LIKE '%aa%';
EXPLAIN SELECT id,NAME,age,email FROM tbl_user WHERE NAME LIKE '%aa%';

需求分析:查询时字段两边都是%,且索引不能失效

创建索引(覆盖索引)

#create index
CREATE INDEX idx_user_nameAge ON tbl_user(NAME,age); #DROP INDEX idx_user_nameAge ON tbl_user

分析:email字段并没有创建索引,覆盖索引失效

覆盖索引:建立的索引字段和查询的字段在个数、顺序上最好完全一致。

9、字符串不加单引号索引失效

底层进行转换使索引失效,使用了函数造成索引失效

10、少用or,用它来连接时会索引失效

【总结】

带头大哥不能死

中间兄弟不能断(永远要符合最佳左前缀原则)

索引列上无计算

like百分加右边

范围之后全失效

字符串里有引号

MySQL索引优化与分析(重要)的更多相关文章

  1. Mysql 索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  2. mySql索引优化分析

    MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字 ...

  3. 重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化

    重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化 一:Mysql原理与慢查询 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能 ...

  4. 知识点:Mysql 索引优化实战(3)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 索引原理知识回顾 索引的性 ...

  5. MySQL索引优化步骤总结

    在项目使用mysql过程中,随着系统的运行,发现一些慢查询,在这里总结一下mysql索引优化步骤 1.开发过程优化 开发过程中对业务表中查询sql分析sql执行计划(尤其是业务流水表),主要是查看sq ...

  6. MySQL索引优化看这篇文章就够了!

    阅读本文大概需要 5 分钟. 来源:cnblogs.com/songwenjie/p/9410009.html 本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引 ...

  7. mysql索引优化比普通查询速度快多少

    mysql索引优化比普通查询速度快多少 一.总结 一句话总结:普通查询全表查询,速度较慢,索引优化的话拿空间换时间,一针见血,所以速度要快很多. 索引优化快很多 空间换时间 1.软件层面优化数据库查询 ...

  8. 讲真,MySQL索引优化看这篇文章就够了

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL——索引基础 首先,我们将从索引基础开始介绍一下什么 ...

  9. mysql索引优化

    mysql 索引优化 >mysql一次查询只能使用一个索引.如果要对多个字段使用索引,建立复合索引. >越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间 ...

随机推荐

  1. Vim 命令、操作、快捷键(收藏大全)

    ------ 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filenam ...

  2. BZOJ 4417 Luogu P3990 [SHOI2013]超级跳马 (DP、矩阵乘法)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4417 (luogu)https://www.luogu.org/prob ...

  3. Oracle-RAC sysdate和current_date时间不一致,导致客户端连接时间延迟

    [oracle@oracle-db1 ~]$ dateTue Oct 10 14:20:56 CST 2017[oracle@oracle-db1 ~]$ cat /etc/sysconfig/clo ...

  4. Mybaits 运行原理流程时序图

    1 .初始化sqlsessionFactory 2openSession 3.getMapper返回接口的代理对象 包含了SqlSession对象 4.查询流程

  5. 常量const实践

    这篇文章写的很好:https://www.cnblogs.com/zhangfeionline/p/5882790.html 自己是实践: 1. 定义时必须初始化值,不然如下错误: 2. 3. 使用:

  6. linux fedora原生的快捷键操作

    显示桌面: ctrl+alt+d 运行终端程序: gnome-terminal : 可以自定义快捷键: ctrl+T 等等.

  7. TP3.2写分页

    用TP3.2写分页 手册上说的好难懂,我自己去网上找资料 ,现在整理一下,以后可能会用: 在Think下面有Page.class.php类: 我在这个下面放了一个function.php的(算是类吧又 ...

  8. js监听当前页面再次加载

    document.addEventListener("visibilitychange", function () { if (!document.hidden) { //处于当前 ...

  9. centos7:Zookeeper集群安装

    将安装包上传到安装目录 解压文件 tar -zxvf zookeeper-3.4.12.tar.gz 移动解压后的文件到软件目录 mv zookeeper-3.4.12 /home/softwareD ...

  10. python 爬虫入门1 爬取代理服务器网址

    刚学,只会一点正则,还只能爬1页..以后还会加入测试 #coding:utf-8 import urllib import urllib2 import re #抓取代理服务器地址 Key = 1 u ...