1、尽量避免使用子查询
2、避免函数索引,比如在判断条件中,使用某函数(a)的形式,即使a有索引,也会直接扫描全表
3、用in替换or
MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。
再例如:select id from table_name where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了;再或者使用连接来替换。
4、LIKE前缀%号、双百分号、_下划线查询非索引列或*无法使用到索引(模糊查询),如果查询的是索引列则可以
5、读取适当的记录LIMIT M,N,而不要读多余的记录
6、避免数据类型不一致
7、分组统计可以禁止排序sort,总和查询可以禁止排重union all
分组统计比如group by,默认情况下,MySqL对所有group by后的字段进行排序,为了避免排序结果的消耗,则可以指定order by null禁止排序
总和查询的话,如果不考虑去重的话,可以只用union all,避免去重产的消耗
8、避免随机取数据,比如使用rand时,ceil(n),取大于等于数值n的最小整数
9、禁止不必要的ORDER BY排序,比如对group by语句的结果没有排序要求,要在语句后面加 order by null(group 默认会去排序)
10、不要使用not等负向查询条件
你可以想象一下,对于一棵B+树,根节点是40,如果你的条件是等于20,就去左面查,你的条件等于50,就去右面查,但是你的条件是不等于66,索引应该咋办?还不是遍历一遍才知道。
11、尽量不用 select *
SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);
(LJ)增加了使用覆盖索引的可能性;
当表结构发生改变时,前者也需要经常更新。所以要求直接在select后面接上字段名。
12、区分in 和 exists,IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况
13、优化Group By 语句
- 如果对group by语句的结果没有排序要求,要在语句后面加 order by null(group 默认会去排序);
- (LJ)尽量让group by过程用上表的索引,确认方法是explain结果里没有Using temporary 和 Using filesort;
- 如果group by需要统计的数据量不大,尽量只使用内存临时表;也可以通过适当调大tmp_table_size参数,来避免用到磁盘临时表;
- (LJ)如果数据量实在太大,使用SQL_BIG_RESULT这个提示,来告诉优化器直接使用排序算法(直接用磁盘临时表)得到group by的结果。