优化器追踪

  1. 查看优化器状态
    • show variables like ‘optimizer_trace’;
  2. 会话级别临时开启
    • set session optimizer_trace=”enabled=on”,end_markers_in_json=on;
  3. 设置优化器追踪的内存大小
    • set OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;
  4. 执行自己的SQL
    • select host,user,plugin from user;
  5. information_schema.optimizer_trace表
    • SELECT trace FROM information_schema.OPTIMIZER_TRACE;
  6. 导入到一个命名为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. 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,这样效率就会因此得到提高

https://www.php.cn/sql/458772.html