开发者学堂课程【MySQL 高级应用 - 索引和锁:索引优化1】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/598/detail/8613
索引优化1
内容介绍
一、建表
二、索引优化
一、建表
首先我们建表:
CREATETABLE staffs(
id INT PRIMARY KEY AUTO _INCREMENT,
NAME VARCHAR (24) NOT 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 '
入职时间"
) CHARSETutf8COMMENT '
员工记录表';
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());
SELECT*FROM staffs;
ALTER TABLE Staff ADD INDEX idx_staffs _ nameAgePos (name, age, pos);
我们复制输入后得到:
二、索引优化
有表后我们开始,下面是10条是索引失效的案例:
1.全值匹配我最爱。
2.最佳左前缀法则。
3.不在索引列上做任何操作(计算、函数、(自动 or 手动)类型转换),会导致索引失效而转向全表扫描。
4.存储引擎不能使用索引中范围条件右边的列。
5.尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少 select*。
6. mysql 在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描。
7. is null,is not null 也无法使用索引。
8. like以通配符开头('%abc.... ')mysql 索引失效会变成全表扫描的操作。
9.字符串不加单引号索引失效。
10.少用 or,用它来连接时会索引失效。
11.全值匹配我最爱
我们输入mysql>show index from staffs;
得到:
我们看到现在有一定的顺序,是因为我们建表时已加上复合索引 staffs,我们建了三个表 NAME、age、pos,这时我们继续输入:
mysql> EXPLAIN SELECT * FROM staffs WHERE NAME ='July;
我们得到:
全值匹配是个数+顺序,我们用到其中一个表,这时是不会失效的,我们继续:
mysql> EXPLAIN SELECT * FROM staffs WHERE NAME ='July' AND age=25;
得到:
现在我们 ref 有两个 const,此时用到两个表,同样未失效我们继续:
mysql> EXPLAIN SELECT * FROM staffs WHERE NAME ='July' AND age=25 AND pos='dev'
;
结果如下:
我们发现三表载入都没有失效,接着我们看:
输入:mysql> SELECT * FROM staffs;
得知 age 的值是23,继续输入:
mysql> EXPLAIN SELECT * FROM staffs WHERE age=23 AND pos='dev'
;
得到:
此时索引失效,type 成了 all,换一种:
mysql> EXPLAIN SELECT * FROM staffs WHERE pos='dev'
;
我们看:
依然如此,我们继续:
mysql> EXPLAIN SELECT * FROM staffs WHERE NAME ='July;
这时我们就回到开始只用到 NAME,发现:
并未失效,我们发现我们跳过了 NAME,从age、pos 开始,就会失效,因为他违背了最佳左前缀法则。
2.最佳左前缀法则。
如果索引了多列。查询从索引的最左前列开始并且不能跳过索引中的列。我们看上面所建的表,NAME、age、pos,NAME 就是最左前列,若没有他,索引就会失效。
此时看:
mysql> EXPLAIN SELECT * FROM staffs WHERE NAME ='July' AND pos='dev'
;
取出了 age ,结果如下:
此时索引未失效,但 const 还是一个,这就用到的是全值匹配的部分使用,这是因为最佳左前缀法则不能跳过索引中的列。