优化器追踪
- 查看优化器状态
- show variables like ‘optimizer_trace’;
- 会话级别临时开启
- set session optimizer_trace=”enabled=on”,end_markers_in_json=on;
- 设置优化器追踪的内存大小
- set OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;
- 执行自己的SQL
- select host,user,plugin from user;
- information_schema.optimizer_trace表
- SELECT trace FROM information_schema.OPTIMIZER_TRACE;
- 导入到一个命名为xx.trace的文件,然后用JSON阅读器来查看(如果没有控制台权限,或直接交由运维,让他把该 trace 文件,输出给你就行了。 )。
- SELECT TRACE INTO DUMPFILE “E:\test.trace” FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
注意:不设置优化器最大容量的话,可能会导致优化器返回的结果不全。
主要看 rows_estimation considered_execution_plans
基本写法优化
1、少使用select ,尽量使用具体字段;
2、对于条件来说等号之类两边的字段类型要一致,不一致索引失效,字符串不加单引号索引会失效;
3、尽量少使用Order By 排序,对于需要多个字段进行排序的可以使用组合索引;
4、对于group by 语句要先过滤后分组;
5、在查询时减少使用null,对字段有多个null的可以加默认值;
6、少使用like,对于需要使用的, 如需要使用尽量用 like abc%这种,不要把%放字段前面;
7、在where后面少使用函数或者算数运算;
8、去除的distinct 过滤字段要少,避免 distinct ;
9、不要超过5个以上的表连接。
建立使用合适索引
1、对于高频筛选字段可以适当的建立索引;<br /> 2、一个表的索引最好不要超过5个,多了会影响插入修改;<br /> 3、不要对值是有限重复的字段建立索引,如性别等;<br /> 4、使用组合索引一定要遵守最左原则;
替代优化
1、不要使用not in 和<>,这个会破坏索引,not in 可以用not exists 来代替,<>可以分成两个条件 >或者<等;
- select * from 表A where id in (select id from 表B)
上面SQL语句相当于
select from 表A where exists(select from 表B where 表B.id=表A.id)
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
2、使用连接(join)来代替子查询; <br />3、用where字句替换HAVING字句
- 避免使用HAVING字句,因为HAVING只会在检索出所有记录之后才对结果集进行过滤,而where则是在聚合前刷选记录,如果能通过where字句限制记录的数目,那就能减少这方面的开销。HAVING中的条件一般用于聚合函数的过滤,除此之外,应该将条件写在where字句中
4、使用表的别名
- 当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个列名上。这样就可以减少解析的时间并减
少哪些友列名歧义引起的语法错误
5、用union all替换union
- 当SQL语句需要union两个查询结果集合时,即使检索结果中不会有重复的记录,如果使用union这两个结果集同样会尝试进行合并,然后在输出最终结果前进行排序,因此如果可以判断检索结果中不会有重复的记录时候,应该用union all,这样效率就会因此得到提高
