一、关于索引
1、对关联关系字段、常用查询条件且基数高的字段(对于低基数字段如性别建立索引所提供的性能提升有限)、排序字段、唯一值字段建立索引
2、索引字段值应该尽量简短,字段太长会影响索引效率,如果一定要对大字段创建索引,可以考虑前缀索引
即:CREATE INDEX idx_field_prefix ON table (SUBSTR(field, 1, 10));
select field... from table where field like 'content%';
3、复合索引的创建,越频繁使用的字段应该放在更左侧,字段不能过多
- 过多字段会增大索引维护开销、存储成本
- 并非所有查询都会涉及到多个索引列,应该经常结合使用的字段组合成为复合索引
- 复合索引太大也会影响到内存效率
- 复合索引字段过多,会导致索引扇出过高,虽然会提高数据读取的效率,不利于数据的写入能力
4、复合索引包含列不是越多越好,索引数量也不是越多越好 索引虽然提高了 select 的效率,但是也降低了 insert 和 update 的效率,创建索引应该谨慎
5、避免回表,应该尽量使用覆盖索引
6、对于复合索引的使用,应该满足最左匹配原则
例如:index(a, b, c),则where语句中条件应为 a = ? and b = ? and c = ?
- 最左匹配原则只要满足最左前缀就可以利用索引
- 查询条件中的范围查询条件右侧的字段不能使用索引
- 可以配合覆盖索引一起使用
7、对于索引类型,范围查询和排序操作,应该选择B-Tree,确定值匹配应该选择Hash
8、为了系统后期维护和数据可靠性,尽量不要使用外键
9、应该善于使用explain来判断sql对索引的使用情况
10、一定要定期维护索引列
二、关于SQL
1、创建表应该选择合适的的存储引擎。绝大多数情况下,数据表应该创建主键
2、select 查询应指定具体的字段。可以考虑利用MyBatis的 <sql> 标签定义字段sql片段
3、创建表的时候字段应该尽量为 NOT NULL ,不管是后期维护优化或者是开发过程,不用判断字段是否为null都是非常友好的
4、对有空值字段的表的查询,应该尽量避免在 where 语句中对字段进行 null 值判断
5、对于非确定值的查询,应该避免在 where 语句中使用 != 、<> 符号,会导致索引失效
6、对于连续的值的判断,能用 between 就不要用 in,如果范围太大的情况下,使用in会进行全表扫描,也尽量避免使用 not in,因为大多数情况下 not in 不会使用索引
7、使用 in 的时候,越频繁使用的字段应该尽量放前面,减少判断次数
8、对于 like %,应该确保 % 前面是确定前缀,以此来使用索引
9、在创建字段的时候能用数字类型尽量使用数字类型字段,可以提升查询的性能,减小存储开销
10、能不用临时表就不要用临时表,毕竟要跨数据通信,会影响速度
11、对于大数据量、复杂且重复使用的关联关系的查询可以尝试用临时表,降低对主表的压力、竟争压力,提高并发能力。但是,大数据量、大字段或者复杂的关联关系,应该首先考虑是否是表设计不合理?
12、避免考虑复杂情况,尽量不使用nolock,一定要使用nolock需要考虑是否会拿到脏数据
13、联表查询,关联表的数量尽量不要超过5个,尽量用别的方式来代替多连接的情况,比如临时表
14、联表查询应该小表驱动大表
15、对于主要业务表,能不用子查询就不用子查询
16、尽量将数据的处理逻辑放在代码层面,或者存储过程(当然,平时接触少就还是别用吧),系统瓶颈大多都在数据库,那就让数据库单纯地存储数据就好了
17、使用 gourp by 时,尽量将过数据滤条件放在之前,可以提升效率
18、where 条件语句中应该避免使用 or 连接条件,会导致索引失效进行全表扫描 最好是用 union all 合并查询
19、应该避免在 where 语句中使用函数、表达式,并且需要保证数据类型匹配,否则会导致全表扫描
20、尽量避免大事务