基于索引层面mysql
1,覆盖索引 实际上SELECT要查询的数据都已经包含在索引中了(不 论是要查询的列,仍是查询的WHERE条件),这样查询能够再也不在走表,减小查询数据的次数sql
2,索引下推 好比where 条件为 deptno like 'A%' and empno like 'B%' ,且当前有一个联合索引为(deptno,empno),那么索引的执行会有两种方式
1)根据deptno查找全部符合条件的记录,根据mysql的二级索引须要回表查询回相应行的方式回到取表全部的记录,再根据empno的查询要求检索出相应的记录
2)根据deptno查找全部符合条件的记录,不回表直接从符合的结果再选出符合empno查询要求的记录,再回表读取出数据。
mysql默认使用索引下推,目的在于减小回表查询记录的条数数据库
3,最左前缀 当前建立联合索引(deptno,empno)
数据库中有记录分别为deptno,empno=[{10,11},{10,12},{11,21},{12,22},{30,31},{30,32}] 那么当where 条件写成 where deptno like '1%' and empno like '2%' 的时候。最左前缀的deptno条件会先取到知足条件的记录范围,再在这个范围内读取查询相应的记录。这个功能点要和MYSQL索引的B+树结构联系。服务器
B+树结构中各最终叶节点前有先后顺序关联,这个关联特性有利于最左前缀的展开并发
4,不要在where条件中对某列进行进行函数计算 ,好比 where f(x)=y(z)+20 .由于对索引的利用至关因而去直接匹配索引中所保存的值进行对比比较。一旦引入的函数计算,就意味着要对每一个索引值都进行一次计算后才能肯定是否符合条件ide
5,索引尽可能包括group by ,order by 字句对应的列。 由于group by 与 order by 都会涉及到结果集的排序操做。尤为当相应的结果集较大且SQL密集时会触发临时表空局内的大规模排序操做 好比在执行计划中的extra列中能够见到 file sorts提示 这种提示就意味着可能出现了排序操做,甚至会致使因SQL查询出现数据库链接中断的状况。在group by ,order by 对应的列上增长索引,利用索引的自然排序性减小或消除在列表空间中的排序操做。既减低SQL结果反馈的时间,又减轻对临时表空间需求的压力函数
6,对于删除了大量数据或者插入数据的表,可使用OPTIMIZE TABLE的操做来从新对innodb表的主键进行物理层面上的调整性能
基于SQL书写的
1,尽可能用UNION ALL 而不是UNION
UNION ALL 是简单的返回结果集相加,不存在去重操做。而UNION 看起来简单,反倒在结果集合并时进行了去重操做,对于不须要去重的查询结果集,这等于多作了无谓操做,下降SQL效率测试
2,能用EXISTS尽可能不用IN,能用表关联尽可能不用子查询。优化
IN 只用于有肯定有限个参数值时使用好比 IN ('36','23','38') ,并且尽可能不要过百
IN EXISTS 和表关联,大概来讲都是各类形式的表关联。当用了IN和EXISTS等在于在语境上告诉SQL解析器你必需要这种形式作表关联,那么SQL解析器将没法发挥调优的做用。也就是说IN和EXISTS最好的执行状况其实也和表关联时SQL解析器分析出的通常结果差很少,不会比它好多少。至于IN和EXISTS间就不作区别说明了
基于慢查询日志定位慢查询SQL根据执行计划进行调优
在查询慢SQL以前首先要定义一个合理的慢查询SQL阈值,好比先定义2秒查询返回的查询是慢查询。当先把这些慢查询清理后再逐步压低阈值,好比到300ms,再到100ms,分期分批,由紧至缓逐步推动
在检索出来的慢查询SQL中主要关注一下几个指标
1,QUERY_TIME 最直观的查询时长
2,ROWS_EXAMINED 检索了多少条记录 若是where条件或者表联接定义的很差,那么对这个值的影响就会比较大
3,ROWS_SEND 结果集记录的数量,若是查询返回1W条,速度确定是比查询返回1条要慢
查询出慢SQL之后将相应的SQL对应的执行计划打印出来,观察执行计划的状况,有的放矢地进行调整
EXPLAIN select ………… 经过这种方式获取相应的执行计划
执行计划中会包括 id,select_type,table,type,possible_keys,key,ken_len,ref,rows,extra等列
其中id列是一组数字,其表示的是这个SQL语句中每一个SQL单元执行的顺序,当序号不一样时大序号的单元先执行,小序号的单元后执行。当序号相同时排在上边序号的单元先执行,下边的后执行
好比 id 返回为
1,
2,
3,
3,
4,
5,
那执行的顺序为 5,4,3(第3行) ,3(第4行),2,1
根据这个顺序去逐一观察整个SQL的执行步骤
select_type列表明每一个子句的类型,是比较简单的仍是比较复杂的
simple 是最简单的,没有子查询也没有union, 最普通的where条件执行的结果
primary 说明有复杂的子部分,它的最外边会被标记为primary
subquery SQL中包含子查询(能够关注是否能够性能调整)
DERIVED 衍生 本人理解为 一大段SQL的结果我把它当成表来使用好比
select from a ,(select from b) c 这里边的(select * from b) 会触发DERIVED 、
UNION 大SQL中存在对UNION 或者UNION ALL的使用,能够关注是否有性能调整点
type列的取值范围有all,index,range,ref,eq_ref,const,system null
all 全表扫描 通常来讲在须要调优的复杂SQL中all的必需要调整掉,若是必要能够增长相应的查询条件,避免这种全表扫描
index 也是一种全表扫描,只是它是遍历整个索引,而不是整个表
range:索引的范围扫描,好比 deptno > 10 and deptno <30
ref:非唯一性索引扫描 好比对emp表写SQL select * from emp where depnto = '2'
这里的deptno 就是非唯一型索引列
eq_ref:唯一型索引列 好比对emp表写SQL select * from emp where empno = '2'
const,system 当表里只有一行的时候会有这种提示,到这个程度通常是不须要优化的
null:不访问表也不访问索引
经过执行计划调优主要就是看这两个列的状况,尽可能减小最糟执行的出现
另外rows列也须要关注
rows列的数值很大可是执行很快的SQL,每每会是某个咱们在本地测试毫无压力可是到服务器上却致使业务变满的根本缘由
本地很快是由于这种SQL在本地跑时因为硬件资源许可因此速度很快。但在服务器上大量相同语句并发时可能会对系统的IO,BUFFER等资源形成争用,致使性能急剧降低
extra列中主要须要关注是否有 files sort 或者 using temporary 若是有这种提示。那说明SQL会在临表空间作排序,这个对SQL的查询速度影响很大,同时也对临表空间的压力很大。若是存在问题考虑增长临表空间,同时看看是否须要对排序或者group by 的列增长索引
另外还有基于DB参数的调整,之后整理