数据库优化无论实在面试还是工作中都非常重要,结合个人多年的从业经验,它主要从数据库设计、sql优化、服务器优化等方面来进行。
数据库设计优化
表设计方面
- 1)表的数据类型是否合理,要遵守选取数据类型越简单越小的原则
- 2)表中碎片是否整理
- 3)表的统计信息是否收集,只有统计信息准确,执行计划才能帮助优化SQL
- 4)表设计时候增加必要的注释,说明字段的用途
字段设计方面
- 1)使用varchar替代char
varchar的存储是按实际长度来存储的,可以节省存储空间,而char是按照定义长度来存储的,不足补充空格
sql优化
常规优化
- 1)尽量不要使用
select *
,而是使用具体的字段
避免了不需要的列返回给客户端调用,节约流量,select *
可能会用到覆盖索引,直接从索引中获取要查询的列数据,减少了回表查询,调高查询效率 - 2)避免在where子句中使用OR来进行条件关联,有可能造成索引失效
- 3)尽量使用数值类型代替字符串
处理引擎在执行查询和连接时候,如果是字符串类型则会逐个比较字符,要是数值类型的话直接比较一次就可以了,字符串的连接性能也会大大降低。 - 4)应尽量避免在where子句中使用!=或<>操作符
这种情况可能会造成索引失效,经过sql优化器优化,执行引擎发现使用索引的代价比不走索引还要大,就会放弃使用索引直接走全表扫描 - 5)在inner join 、left join、right join都满足条件的状况下,优先使用inner join
inner join内连接,只保留左右两张表中都匹配的结果集;left join 左连接,以左表为主表,返回左表中的所有行,即使右表中没有匹配的行;right join右连接,以右表为主表,返回右表中的所有数据,即使坐标中没有匹配的行;如果是inner join等值连接,返回的行数比较小,所以效率较高;左右连接的话,按照“小表驱动大表的原则”,用小表作为主表 - 6)遵循“小表驱动大表”的原则
在含有复杂子查询的sql语句中,在满足条件的情况下,应该将小表放在里面层层过滤,缩小查询的范围 - 7)分组过滤的时候,应该先过滤,再分组
- 8)执行delete或update语句,加个limit或者循环分批次删除
降低误删数据的代价,避免长事务,数据量大的话,容易把cpu打满,一次性删除数据太多的话可能造成锁表 - 9)用union all替代union
union会对筛选掉重复的记录,所以会在连接后对所产生的结果集先进行排序运算,然后再删除重复记录返回,如果数据量比较大的情况下可能会使用磁盘排序 - 10)多条写数据,建议采用批量提交减少事务提交的次数,提高性能
- 11)关联查询的表连接不要太多
关联表的个数越多,编译的时间和开销也越大,每次关联在内存中都会产生一个临时表 - 12)索引并不是越多越好
索引虽然提高了查询性能,但是会降低数据写入的速度,并且索引的存储是要占用空间的,索引也是排序的,排序是要花费时间的,insert和update操作可能会导致重建索引,如果数据量巨大,这笔消耗也是非常惊人的 - 13)去重distinct过滤字段要少
数据库引擎对数据的比较、过滤是一个很耗费资源的操作 14)尽量避使用游标
索引优化
- 1)通过explain,查看执行计划,检查索引使用情况,没有用到索引,考虑创建
- 2)创建索引前,查看索引的选择性distinct,判断该字段是否适创建索引
索引选择性指不重复的索引值和数据记录总数的比值,越接近1越好;主键索引和唯一索引选择性是1 - 3)创建索引后,再查看执行计划,对比两次结果,查看效率是否提高
慢查询优化
- 1)如果一个select语句中没有where条件,只有单纯的group by | order by,这是无法使用索引的。需要有where作为基础铺垫,遵从最左原则才能使用索引。