1.主键格式为整型或uuid格式,建议使用int避免数据库底层b+tree的page频繁分裂,导致大量io
查询语句优化
2.查询结果最好分页,每页最好不超过1000 mysql默认值
3.join表数量尽量不超过3个(解决办法添加冗余字段)
4.left join尽量用数据量小的表作为左表,right join尽量用数据量小的表作为右表 (因为左连接的话,左表是全量的,右表,右表是全量的)
5.条件部分尽量不使用函数或表达式,因为无法命中索引,部分数据库无法利用计算下推到存储层优化
6.select 指定的字段尽量完全包含在索引的字段列表中(索引覆盖的知识
InnoDB聚集索引和普通索引 聚集索引 叶子节点记录值,普通索引叶子节点记录主键值,导致普通索引会有回表查询
解决办法:建立索引,联合索引)
7.除非count某个单独字段,其余均使用count(*),数据库查询优化器会自动使用count(1)查询
(count(字段),非主键字段,这样的使用方式最好不要出现。因为它不会走索引)
8.禁止使用随机值作为order by字段,除非数据量很小(order by 字段必须为有序重复少的)
9.distinct字段必须添加索引,除非数据量很小,或者其他部分已经命中索引,且字段与distinct不同
10.group by的字段至少要有一个字段添加索引,除非聚合前结果集数据量很小或者其他部分已经命中索引,且字段与group by不同
11.order by的字段至少要有一个字段添加索引,除非排序前结果集数据量很小或者其他部分已经命中索引,且字段与order by不同
12.禁止select所有数据,除非能确保数据量永远很小
13.查询语句条件中包含变量的,应使用prepare提交占位符,execute时bindvalue的方式执行,规避sql注入风险
(MySQL官方将prepare、execute、deallocate统称为PREPARE STATEMENT)
14.如果包含条件部分,必须至少有一个字段添加了索引,字段不等于某个值时无法利用索引
通用规范
1.In 条件个数,adb for mysql不超过2000个,mysql建议不超过500,mysql不强制,其余数据库查看相应的限制,非限制的建议不超过500,非限制的不强制。如果IN字段为索引字段,建议不超过10个,对IN括号内数据进行排序,分批查询,使用union all合并结果集,并且在线上真实数据环境验证
2.禁止在migration中使用drop table、truncate、drop database,单条sql删除或更新大量数据,避免migration重复误执行,导致不良后果,除非开发人员对这些后果有明确认知
3.事务中不建议包含异步操作,比如produce消息队列消息,调用外部api,执行shell等,通常这些操作不能满足事务的ACID要求,可能会导致数据不一致
4.禁止使用hint,做类似建议数据库对sql语句条件部分的查询计划使用哪个索引的操作,因为查询条件的值可能会随业务发生变化,无法保证绝大部分情况都是最优的,因此应该尽可能相信数据库自身的专业优化器生成的查询计划
5.事务中sql不超过5个,尽量避免大事务
Delete规范
1.必须包含条件部分,否则使用truncate代替(不允许使用drop),字段不等于某个值时无法利用索引
2.delete语句条件部分必须至少有一个字段添加了索引,否则可能会导致锁表
3.尽量使用主键作为条件delete,减少加锁的数据范围,提高并发度
Update规范
1.禁止更新主键
2.如果包含条件部分,必须至少有一个字段添加了索引,否则可能会导致锁表,,字段不等于某个值时无法利用索引
3.一般情况必须包含条件部分,如果确实不需要条件,需谨慎确认,可能会锁表
4.尽量使用主键作为条件更新,减少加锁的数据范围,提高并发度
Insert 规范
1.insert批量插入数量建议不超过5000,否则如果有主从可能会导致同步延迟