建表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. 详解cocos2dx 3.0的release版本在android平台的签名过程

    当您的游戏准备发布前,需要编译成为release版本,命令中需要增加 -m release,编译命令如下: cocos compile -p android -m release 在编译结束后,生成x ...

  2. [CSP-S模拟测试]:格式化(贪心)

    题目传送门(内部题105) 输入格式 每组数据第一行一个正整数$n$,表示硬盘块数,接下来$n$行,每行两个正整数,第一个正整数为硬盘格式化前的容量,第二个正整数为格式化之后的容量. 输出格式 对每组 ...

  3. jQuery file upload callback options

    autoUpload By default, files added to the widget are uploaded as soon as the user clicks on the star ...

  4. webpack.config.js文件

    与 package.json 配合使用 var path=require("path");var OpenBrowserPlugin = require('open-browser ...

  5. layui table指定某一行样式

    1.想指定layui table中某一行的样式,找了这个资源可行.转自: https://blog.csdn.net/weixin_44729896/article/details/100524824 ...

  6. Android Studio 安装 Flutter

    1 下载sdk https://flutter.dev/docs/get-started/install/windows   2 解压到自定义文件夹,并配置bin路径到环境变量path中 path添加 ...

  7. -----------------解决天天模拟器不能连接adb命令

    cmd------输入adb connect 127.0.0.1:6555即可 查询日志:adb shell "logcat |grep OkHttp"

  8. Python Module_subprocess_子进程(程序调用)

    目录 目录 前言 软件环境 认识subprocess Popen Constructor构造函数 Class Popen的参数 args 调用程序 调用Shell指令 stdinstdoutstder ...

  9. anr以及nlp语音自动化测试方案

    进行asr自动化测试 1.将人工语音录制的音频文件分为一句话一个文件,并将文件名命名为此句话,可以加后缀,例如:附近的公园_1 2.使用电脑连接蓝牙音箱,控制好距离角度等环境 3.使用python或者 ...

  10. Chapter03 第一节 简单变量

    3.1 简单变量 定义一个变量后,系统根据变量类型的不同在内存的不同区域分配一个空间,将值复制到内存中,然后用户通过变量名访问这个空间. 3.1.1 变量名 变量名的命名规则: 只能使用字母.数字.下 ...