- 1.Where、Order by、Group by、Distinct、多表Join涉及的字段一定要有合理的索引
- 2.避免数据类型的隐式转换
- 3.对应同一列进行or判断时,使用in代替or,但in的值不要太多 *
- 4.禁止使用%进行前缀匹配
- 5.避免使用负向查询 *
- 6.Where从句中禁止对列进行函数转换和计算 * 虚拟列**
- 7.禁止非必要情况下使用Select * ,要使用Select <字段列表> 查询
- 8.避免使用Join关联太多的表,尽量不超过3张表,最多不超过5张
- 9.禁止使用Order by rand() 进行随机排序
- 10.减少同数据库的交互次数,数据库更适合处理批量操作合并多个相同的操作到一起,可以提高处理效率
- 11.在明显不会有重复值时使用Union all而不是Union
- 12.拆分复杂的大SQL为多个小SQL
- 13.大批量写(Update、Delete、Insert)操作,要分批多次少量进行操作,建议使用Limit和Select sleep(1);结合使用 *
- 14.建议慎用不含字段列表的Insert语
- 15.禁止使用 insert b select * from a;
- 16.建议使用合理的分页方式以提高分页效率 *
- 17.禁止在生产环境主库进行查询分析统计操作,必要时请申请专用统计从库
- 18.非必要不要开启程序的自提交模式,慎用set autocommit=0;
- 19.避免使用子查询,可以把子查询优化为Join操作
- 20.获取唯一行时使用limit 1 *
- 21.索引并对连接使用同样的字段类型
- 22.拆分大型delete或insert语句
1.Where、Order by、Group by、Distinct、多表Join涉及的字段一定要有合理的索引
2.避免数据类型的隐式转换
释义:会导致使用不上索引,如:select name,phone from customer where id = ‘111’; id是int类型,如果加上引号,就会按照varchar类型转义,所以数值类型禁止加引号,字符串类型必须加引号
3.对应同一列进行or判断时,使用in代替or,但in的值不要太多 *
释义:or大多数情况下很少能利用到索引,in的值太多的话,也会可能使用不上索引
4.禁止使用%进行前缀匹配
释义:如where aa like ‘%xxx’;MySQL索引遵循最左匹配原则,导致使用不上索引
5.避免使用负向查询 *
释义: 例如 not in、!=、not like、<>等,容易导致使用不了索引
6.Where从句中禁止对列进行函数转换和计算 * 虚拟列**
释义:避免进行函数转换或计算时会导致无法使用索引,如:where date(create_time)=’20190101’(不推荐),where create_time >=’20190101’ and create_time <’20190101’(推荐)
7.禁止非必要情况下使用Select * ,要使用Select <字段列表> 查询
8.避免使用Join关联太多的表,尽量不超过3张表,最多不超过5张
释义:在Mysql中,对于同一个SQL多关联(join)一个表,就会多分配一个关联缓存,如果在一个SQL中关联的表越多,所占用的内存也就越大,如果程序中大量的使用了多表关联的操作,同时join_buffer_size设置的也不合理的情况下,就容易造成服务器内存溢出
9.禁止使用Order by rand() 进行随机排序
释义:会把表中所有符合条件的数据装载到内存中,然后在内存中对所有数据根据随机生成的值进行排序,并且可能会对每一行都生成一个随机值,如果满足条件的数据集非常大,就会消耗大量的CPU和IO及内存资源
10.减少同数据库的交互次数,数据库更适合处理批量操作合并多个相同的操作到一起,可以提高处理效率
释义:alter table table_name add index idx_aa(aa);和alter table table_name add index idx_bb(bb);可以合并成alter table table_name add index idx_aa(aa),add index idx_bb(bb);
11.在明显不会有重复值时使用Union all而不是Union
释义:UNION会把两个结果集的所有数据放到临时表中后再进行去重操作,而UNION ALL不会再对结果集进行去重操作
12.拆分复杂的大SQL为多个小SQL
释义:大SQL:逻辑上比较复杂,需要占用大量CPU进行计算的SQL MySQL:一个SQL只能使用一个CPU进行计算 SQL:拆分后可以通过并行执行来提高处理效率
13.大批量写(Update、Delete、Insert)操作,要分批多次少量进行操作,建议使用Limit和Select sleep(1);结合使用 *
释义:大批量操作可能会造成严重的主从延迟;binlog日志为row格式时会产生大量的日志;避免产生大事务操作,表中大批量数据进行锁定,从而导致大量的阻塞;
14.建议慎用不含字段列表的Insert语
释义:不要 insert into values (‘a’,’b’,’c’);应使用insert into t(c1,c2,c3) values (‘a’,’b’,’c’);
15.禁止使用 insert b select * from a;
释义:对于a表中的数据量不可控,容易导致大量IO和CPU使用,应将select * from a的结果集转换格式分批写到b表中
16.建议使用合理的分页方式以提高分页效率 *
释义:limit的值不宜过大,批量查询时,容易导致大量慢查询
17.禁止在生产环境主库进行查询分析统计操作,必要时请申请专用统计从库
释义:分析统计操作重,容易导致主库资源竞争,业务阻塞甚至宕掉
18.非必要不要开启程序的自提交模式,慎用set autocommit=0;
19.避免使用子查询,可以把子查询优化为Join操作
释义:子查询的结果集无法使用索引,通常子查询的结果集会被存储到临时表中,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响,特别是对于返回结果集比较大的子查询,其对查询性能的影响也就越大,由于子查询会产生大量的临时表也没有索引,所以会消耗过多的CPU和IO资源,产生大量的慢查询
20.获取唯一行时使用limit 1 *
释义:当查询表时,已经知道正在查找的结果只有一行(可能正在获取唯一记录,或者你可能只是查询是否存在满足where子句条件的记录),在这种情况下,将limit 1添加到查询条件中可以提高性能,这样数据库引擎在找到刚刚第一个记录之后停止扫描记录,而不是遍历整个表或索引。
21.索引并对连接使用同样的字段类型
释义:如果应用程序包含许多连接查询,需要确保连接的字段在两张表上都建立了索引。此外,被连接的字段,需要使用同样类型,例如,如果使用了一个decimal类型的字段,连接另外一张表的int字段,MySQL将无法使用至少一个索引。
22.拆分大型delete或insert语句
释义:你如果需要在网站上执行大量的delete或insert,则需要关注不要影响网络流量,当执行大型语句时,它会锁表并使进程或查询堆积。