sql优化篇
简单优化:
1、不要使用 select *,尽量避免回表查询
2、尽量避免 in语句,用exist语句代替
3、如果 like 语句前后模糊匹配导致索引失效,可以使用 SELECT * FROM table WHERE INSTR(name, 'keyword') > 0;
4、优先在where 、order by、group by、on的字段上建立索引,建立联合索引,不建立单个索引,索引字段最好不超过6到8个
5、limit时,尽量添加order by [索引字段],可以在大数据量时提高查询速度
6、order by,
7、使用between and 代替 > 、<、<>、!=,查询数据量大时,需要回表的情况则不走索引,因为回表的效率可能低于全表扫描
8、避免对过滤字段进行 运算,可以把运算 加到 = 号右边,同理不要对 过滤字段使用函数操作
9、
查询计划解读:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
id:一条多子句sql,子句的查询顺序,id越大优先级越高,越先执行
select_type:
system只有一行记录会出现
eq_ref索引字段能匹配到唯一的行,一般主键和唯一键的字段查询可以
ref非唯一,与eq_ref相对
range一定范围内的索引扫描,与index相对
index全部范围的索引扫描
ALL全表扫描,没走索引
possible_keys:你查询的字段可能设置了一些索引,但是where,order by等筛选条件不一定会使用这些索引
key:和possible_keys相对,就是你筛选条件实际使用的索引
key_len:这也是估算值,使用的索引长度(最大可能长度),查询并非是使用索引的全部长度
ref:
rows:这是大致估算的扫描行数
extra:一些比较重要的描述信息,使用到了索引会提示Using index
聚集索引(聚簇索引):叶子节点存储的是整行数据,主键索引就是聚集索引,
非聚集索引(普通索引、非聚簇索引、二级索引):其他的则不是,其他索引只存储索引列的数据以及主键索引
回表查询:使用非聚集索引时,为了取到具体数据,通过主键回到聚集索引里查数据,用执行计划可以看到两次查询
索引覆盖:为了减少或解决回表的一种操作,尽量在筛选条件中加上对主键的一些筛选或者排序操作,或者减少查询列,只查询添加了索引的列
索引下推:mysql5.6版本后才会有
真实案例
比较简单的案例一般是:
混合排序优化,比如查询依然使用索引的排序,查完才使用倒叙;或者多建个倒叙索引
模糊查询优化,刚才提到的用函数INSTR
limit优化,尽量加上where来确定数据范围
还有隐式转换的问题