表的优化
1. 选取适用的字段属性和大小
一般来说的数据库中的表越小,在表中执行查询的效率也就越高,因此在创建表时,为获得更好的性能,我们应该将表的宽度设计得尽可能小,前提是符合业务需求。
例如:在设计漏洞id字段的时候,如果将其设置成varchar(64),显然是不合适的,使用varchar(20)即可完成业务需求,同时由于漏洞id是长度定型的字段,因此在设计漏洞相关表时,完全可以直接采用varchar(20)。
2. 尽可能使用可变字段代替固定字段
固定字段需要占用固定的长度,而可变字段可以动态的缩小字段长度,节省存储空间,缩小表的规模,对于查询来说,在一个相对较小的字段内搜索效率显然更高。
例如:使用varchar代替char
3. 字段类型统一
对于多表联查时,如果join的外键字段类型不统一,可能会导致索引失效,从而全表扫描。
例如:此处可参考由vms_pbi 表中的pbi_id字段引发的问题,vms pbi表采用bigint类型存储字段,但是在相关表外键字段中却采用varchar字段,导致类型不匹配,mysql默认进行隐式类型转换,从而导致pbi表索引失效,严重影响查询效率,查询达到60s,性能严重不达标。
4. 尽量使用数字型字段
如果是只包含数值信息的字段尽量不要设计成字符类型,这会降低查询和连接的性能,并增加存储的开销。
这是因为Mysql存储引擎在处理查询和连接时会逐个比较字符串中的每个字符,而对于数字型而言,只要比较一次就够了。
注:使用数字型字段虽然能提升查询效率,但是在实际业务开发过程中,连表查询的类型不匹配和mybatis类型使用不当导致的类型转换,进而导致索引失效,这个问题才是我们关注的重点,切勿捡了芝麻丢西瓜。
索引
5. 复合索引最左前缀匹配原则
mysql在建立联合索引时,会遵守最左前缀匹配原则,即最左优先,同时在检索数据时,会从联合索引的最左边开始匹配,如果sql中联合索引的中间列不在查询条件当中,则联合索引后续的列会失效(索引底层数据结构B+树)。
注:此处并不是说sql的查询条件中包含联合索引的所有列就可以使用联合索引。
6. 联合索引中不会包含由NULL值的索引
只要列中包含NULL值的都不会包含在索引中,复合索引中只要有一列含有NUll值,那么这一列对于此复合索引来说就是无效的,因此我们在数据库设计的时候,尽量不要让字段的默认值为NULL。
注:IS NULL 或 IS NOT NULL 是可以使用上索引的,但是对于实际业务来说一般意义不大。
7. 合理构建和控制索引
索引并不是越多越好,索引固然可以提高响应的select的效率,但同时也降低了insert和update的效率,因为insert和update时有可能会重建索引,所以创建索引应该结合表的业务慎重考虑,一般来说索引数建议不超过6个,若太多,应考虑不太常用的列建立索引的必要性。
SQL
8. 尽量避免在where字句中对字段进行null值判断
在where子句中对NULL值的进行判断,可能导致引擎放弃使用索引而进行全表扫描。最好不要在给数据库表中留null,尽可能使用NOT NULL填充数据库。
9. 尽量避免在where子句中使用 != 或 <>操作符
10. 尽量避免在where子句中使用or类连接条件,如果一个字段有索引,一个字段没有索引
如:
11. in和not in 也要慎用,否则可能导致全表扫描
对于连续的数值,能用between就不要用in
或者使用exist代替in
