9、执行计划分析 9.1、作用 将优化器 选择后的执行计划 截取出来,便于管理员判断语句的执行效率。 9.2、获取执行计划 desc sql语句 desc select * from city where name= 'Kabul';explain sql语句 explain select * from city where name= 'Kabul'; #获取到的是一样的 9.3、分析执行计划
9.3.1、table #表名 9.3.2、type #查询的类型 全表扫描 : 显示All 索引扫描 :index, range , ref, eq_ref ,const(system), NULL (从左到右,等级超高,性能越好) index:全索引扫描 desc select countrycode from city;
range:索引范围扫描(>, <, >=, <=, between, and, or, in, like) desc select * from city where id >2000;
对于辅助索引来讲,!= 和 not in 等语句是不走索引的。 对于主键索引来讲,!= 和 not in 等语句是走 range
![]()
ref:辅助索引等值查询 desc select * from city where countrycode='CHN' union all select * from city where countrycode='USA' eq_ref:多表连接时,子表使用主键或唯一列作为连接条件 A join B on A.x = B.y ##(y列,是B表的主键或者唯一列)
const(system):主键或者唯一键的等值查询 desc select * from city where id=100;
9.3.3、possible_keys: 可能会用到的索引 9.3.4、key:真正选择了那个索引 9.3.5、key_len:索引覆盖长度,作用,判断 联合索引的覆盖长度,一般情况下,越长越好。
utf8mb4 最大的预留长度4 utf8 最大的预留长度3 gbk 最大的预留长度2 varchar(20)----utf8mb4字符集 能存20个任意字符 不管存储的是字符,数字,中文,都1个字符最大预留长度是4个字节 对于中文来讲,1个字符 占4个字节 对于数字和字母,1个字符占用大小是 1 个字节 select length(列) from test;
分别为每列创建一个索引 alter table test add index id(id); alter table test add index k1(k1); alter table test add index k2(k2); alter table test add index k3(k3); alter table test add index k4(k4);
key_len单列:(utf8mb4) 单列,索引长度越小越好 char类型的最大预留长度 + 1(是否允许空,not null 就不加,null 加1) varchar 类型的最大预留长度 + 3(其中1,为null,保留,还有,开始:1,结束:1)
![]()
![]()
![]()
![]()
删除刚才创建的索引,重新创建一个联合索引。 alter table test drop index id; alter table test drop index k1; alter table test drop index k2; alter table test drop index k3; alter table test drop index k4; alter table test add index idx(k1,k2,k3,k4); 联合索引:索引长度越大越好,越大说明用的索引越多。
联合索引应用细节:add index idx(a,b,c,d),第一个索引必须要存在 只要我们将来的查询,所有索引列都是等值查询条件下,无关排列顺序。原因是,优化器,会自动做查询条件的排列。唯一值多的列放在最左侧,这样会过滤掉大部分的数据。 不连续的部分条件(但是,第一个索引[最左列]必须要在,如果不在,则不会走索引。) 在条件查询中没有最左列条件时,没有k1的查询,都是不走索引的,就是,你建立索引的时候,比如idx(k1,k2,k3,k4),查询条时,where 条件中,只有(k2,k3,k4),这样是不会走索引的。 cda------>(重新排列)acd ---->a (只走a的索引)-----优化(建索引 idx(c,d,a))
dba------>(重新排列)abd-----ab (只走ab的索引)-----优化(建索引 idx(d,b,a))
3、在where 查询中如果出现> < >= <= like 此类的查询条件。 desc select * from test where k1='aa' and k2>'中国' and k3='aaaa' and k4='中国你好';
怎么优化上面语句: 删除原来的索引 alter table test drop index idx; 重新创建一个索引 alter table test add index idx2(k1,k3,k4,k2); 把 >的条件放在最后 desc select * from test where k1='aa' and k3='aaaa' and k4='中国你好' and k2>'中国';
4、多子句(有group by 有order by)查询,应用联合索引 desc select * from test where k1='aa' order by k2; alter table test add index idx3(k1,k2);
![]()
必须按照子句的执行顺序去建联合索引 9.3.6、extra: 重点关注 Using filesort(还需要额外的文件排序) 出现: Using filesort,说明在查询中有关排序的条件列没有合理应用索引。 (order by 、group by、distinct、union)会出现排序。关注key_len应用的长度,有没有走全。 explain(desc)使用场景(面试题) 你做过哪些优化? 你作过什么优化工具? 你对索引这块怎么优化的? 我们公司业务慢,请你从数据库的角度分析原因 mysql 出现性能问题,我总结有两种情况 a)、应急性的慢:突然夯住 应急情况:数据库hang(卡了,资源耗尽) 处理过程: show processlist; 获取到导致数据库hang的语句 explain 分析 sql 的执行计划,有没有走索引,索引的类型情况 建索引,修改语句。 如果还是卡,考虑有可能是语句本身的问题,需要开发配合修改。 b)、一段时间慢(持续性的): 记录慢日志slowlog,分析slowlog 。 explain 分析 sql 的执行计划,有没有走索引,索引的类型情况 建索引,修改语句。 ++++++++++++++++++++ 索引应用规范: 建立索引的原则(DBA运维规范) (1)、建表必须要有主键,一般是无关列,自增长。 (2)、经常做为where 条件列 order by group by join on,distinct 的条件列建索引 (3)、最好使用唯一值多的列作为联合索引前导列,其他的按照联合索引优化细节来做。 (4)、列值长度较长的索引列,我们建议使用前辍索引。减少key_len:索引覆盖长度 (5)、降低索引条目,不要创建没有用的索引,不常使用的索引清理,sqlyog,表信息,找出多余索引 (6)、索引维护要避开业务繁忙期 (7)、小表(几百行,几千行)不建索引 不走索引的情况(开发规范) (1)、没有查询条件,或者查询条件没有建立索引 select * from city; select * from city where 1=1; (2)、查询结果集是原表中的大部分数据,应该是25%以上。 查询结果集超过原表中25%的数据,不走索引。 (3)、索引本身失效,统计数据不真实。(大量的对索引列更新数据) 面试题:同一个语句突然变慢? 统计信息过旧,导致的索引失效。 (4)、查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,!)等。 where 后面的条件 有计算 不走索引
(5)、隐式转换导致索引失效
(6)、< >,not in 不走索引(辅助索引) (7)、like "%aa" 百分号在最前面不走索引


分别为每列创建一个索引
alter table test add index id(id);
alter table test add index k1(k1);
alter table test add index k2(k2);
alter table test add index k3(k3);
alter table test add index k4(k4);
key_len单列:(utf8mb4) 单
删除刚才创建的索引,重新创建一个联合索引。
alter table test drop index id;
alter table test drop index k1;
alter table test drop index k2;
alter table test drop index k3;
alter table test drop index k4;
alter table test add index 
dba------>(重新排列)abd-----ab (只走ab的索引)-----

(5)、隐式转换导致索引失效
(6)、< >,not in 不走索引(辅助索引)
(7)、like "%aa" 百分号在最前面不走索引