须要的准备知识mysql
1最左前缀匹配sql
mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就中止匹配,大数据
对于where条件 优化
a = 1 and b> 2 and c = 3spa
若是咱们创建(a,b,c)顺序的索引,blog
那么c 是用不到索引的,若是创建(a,c,b)的索引则均可以用到,a,c的顺序能够任意调整。排序
当咱们创建(a,b)的复合索引索引
对于where条件 it
a = 1 依然是能够用到索引的。io
注意:
=和in能够乱序,好比a = 1 and b = 2 and c = 3 创建(a,b,c)索引能够任意顺序,
mysql的查询优化器会帮你优化成索引能够识别的形式
2 sql索引原则
2.1索引列的区分度尽可能要高,区分度的计算公式count(distinct col)/count(*)
惟一键的区分度是1,而好比相似 状态,性别等字段在大数据面前区分度是0
2.2要保持索引列的值的干净,不能参与计算
好比 假如用户年龄上有索引
Select id from user where age>2 (会走索引)
Select id from user where age-2>0 (不会走索引)
2.3尽可能的扩展索引,不要新建索引。好比表中已经有a的索引,如今要加(a,b)的索引
修改便可。
3优化神器 explain / desc 的使用
在你原来的sql语句以前加上 explain 就能够查看mysql对于该语句的执行计划
以下图所示
type
const(常量链接),好比SELECT * FROM user WHERE id=1;
eq_ref(等值引用),好比SELECT * FROM user,card WHERE user.id=card.userid;
ref(引用),用于非惟一索引,好比SELECT * FROM user,card WHERE user.last_name='test';
range(范围),好比SELECT * FROM tbl_name WHERE key_column > 10;
unique_subquery 子查询 针对惟一索引或者主键
index_subquery 子查询 针对非惟一索引列
index(索引),根据索引来读取数据,若是索引已包含了查询数据,只需扫描索引树,不然执行全表扫描和All相似;
ALL(全部),全表扫描
Extra
Using index:表示使用索引,若是同时出现Using where,表明使用索引来查找读取记录,若是没有Using where,表示索引包含查询数据,无需额外的查找;
Using where:表示条件查询,若是type列是ALL或index,而没有出现该信息,则你有可能在执行错误的查询:返回全部数据;
Using filesort:不是“使用文件索引”的含义!filesort是MySQL所实现的一种排序策略,一般在使用到排序语句ORDER BY的时候,会出现该信息; [非索引字段排序]
Using temporary:表示为了获得结果,使用了临时表,这一般是出如今多表联合查询,结果排序的场合。
咱们须要重点关注rows。
优化方法(步骤)
1.先运行看看是否真的很慢,注意看是否设置了SQL_NO_CACHE。优化以前先关闭。
2.explain查看执行计划,看那些地方比较慢
3.order by limit 形式的sql语句让排序的表优先查(也就是遇到这类状况,咱们能够先去掉order by limit 看是否是他致使的)
4.加索引时参照上面的sql索引原则
5.观察结果,不符合预期继续从1分析