数据库性能优化一

时间:2021-10-05 23:58:51

这周公司组织的去惠州游玩,玩得很开心,就是坐车的时间比较长,除了睡觉基本一半时间都在车上,刚回来吃了饭,原本计划着这周搞点docker的一些知识,不过太累了,就写点个人总结吧。作为IT程序员,特别是做了几年的,三年以上的吧,如果还是觉得只要能实现功能,就万事大吉完成任务,只是着眼与功能点的实现,那可就真成搬砖的了,最基本的是实现功能的优化。一个项目都会包含应用服务器和数据服务器,如果说对项目进行优化,那优化的地方有好多,优化的方法也有好多,今天要说的对数据库的优化也有好几个方面。

一、系统框架方面

1.框架

首先是要搞清楚业务需求,在满足业务需求的情况下,合理的技术选型和系统架构不仅仅是对数据库方面有帮助,对后期的开发维护都有帮助,系统框架要考虑长远,也不是说一个小的企业宣传网站就搞什么分布式、大数据这些,毕竟软件也有生命周期的,但也不能只顾眼前,可以根据自身情况以及对未来五年十年的规划,最起码先有一个目标,能满足多人用户的需求,每天访问量能达到多少、并发量能到多少,未来五年又是一个目标,不能说软件用了一两年数据量一大、人一多就不能用了,扩展性方面要有一定的考虑。

2.业务实现方面

在系统中会进行对数据库的访问,访问的多了超过数据库的承载能力了,就会影响数据库的性能。所以我们可以从系统业务实现方面来进行数据库的一些优化,比如缓存,能减少一些访问次数,比如连接池的设计,也是更减少系统的开销,更好的利用资源,有的项目也会把一些常用的不宜改变的数据放在客户端,这样也能减少对数据库的访问次数。同时一些对应用服务器优化的方法其实也是对数据库的优化,比如队列,利用队列可以达到错峰的效果,这样也可以防止数据库崩溃,导致更大的灾难,增加数据库的抗压能力。还有就是可以减少返回的数据,数据量小了速度也会提升。

二、数据库自身方面

1.表结构的设计

业务需求影响表的设计,同时表的设计影响需求的实现。一般项目都会有登录功能,而且也是比较经常访问的,我见过的大部分的系统,表的设计是将用户登录的密码放在用户个人信息表中,一个用户信息表可能会有二三十个字段,甚至包含手机号、邮箱等一些比较隐私的信息。像这种也是能实现需求的,不过以后用户多的时候,达到百万千万级时,一条记录这么多字段,这么多的用户那一个表的数据也是蛮大的,仅仅是实现登录功能,就可能会查询好久,可能有人会说,这不怕,可以分库分表啊,将一半的数据分到令一个数据表甚至数据库中,这确实是个办法,不过其实登录也就仅仅是用户名和密码、验证码,何必搞那么多呢,而且将用户名密码和个人私人信息放在一起也不安全,万一哪天被盗,那就把个人信息透露完了,如果只把用户名、密码、验证码只与登录有关的放在一个表,那可能自动就会少一些,个人信息泄露的风险也会降低一点。在做功能时,会有单一原则,在做表的设计时也可以考虑,可能有的会说,也不能太单一了,不是有三级范式,可以按照三级范式来进行设计,确实三级范式是一个很好的参考,平时在做表的设计时需要考虑三级范式,不过也有一些情况比较特殊,所以还是权衡着选择。

2.字段的设计

还是拿用户表来说,用户头像也是比较常见的吧,可能有的是直接把头像放入数据库中,图像占的空间也是比较大的,可能所有的个人信息还没一个头像占的空间大,这也导致了数据库容量的增大,其实将头像专门放到一个文件服务器,数据库中只保存一个url也是一种对数据库的优化。

3.sql语句

这个写过sql的应该都会或多或少的了解,查询同样的数据有的sql查询很快,有的就很慢,甚至会有死锁,特别是自己苦思冥想了半天始终憋不出思路或者可憋出来了查询数据很慢,等半天还没结果,另外的小伙伴可能将自己的sql稍微改动改动就会很快查出结果,这种是比较尴尬的。sql语句的优化也有好多注意的,也有好多方法。

4.主键、索引、存储过程等

对表添加主键一般都会有,不管是逻辑主键还是业务主键,但有一些查询可能不是通过主键查的,特别是一些条件查询,比如查询特定时间段的数据,而且使用的也特别频繁,这种可以使用索引来提高速度,存储过程也是,存储过程是预编译的相比直接sql还是好一点的。

5.锁、事务

系统中减少锁与事务的使用,或者减少锁的粒度,防止死锁的发生,对于事务,特别是分布式事务,使用它们都会降低数据库的并发量。有的使用不慎,可能导致系统越来越慢。

三、数据库架构方面

上面对数据库的优化是从单个数据库来说的,也是可以满足一定的用户需求的,如果用户量比较大,访问比较多,数据量也比较大,我们可以对数据库架构进行优化,比如读写分离、分库分表。

1.读写分离

我们都知道二八原则,其实在互联网中也能体现二八原则,用户操作中大部分是浏览,读的操作,一小部分是写的操作,所以读比较频繁,写就相对不频繁,可以将数据库设计成一主多从或多主多从,这样就能减少对一个数据库服务器的压力,同样有利有弊,数据库增多也会带来一些新的问题,比如数据同步的问题,数据库节点变化的问题,增加一个数据库或减少一个数据库可能就会导致一部分用户映射不到。

2.分库分表

分库分表也是分而治之的思想,一个表或一个库的数据比较大,那就放在多个表多个库中,比如一个1000万数据库的表的查询肯定是没有两个500万数据库的表查询快,同样也是有利有弊,可能在系统设计阶段进行分库分表还好分一点,但对数据库或表的水平扩展那就麻烦了,比如增加一个数据库或表,那怎么将原来用户的数据映射到正确的数据库或表中呢。这是均分数据,还有一种分库分表是按时间或者按其他因素来分,比如新闻类的,时效性比较强,用户可能关注的也就一周的信息,那可以将比较热点的访问频率比较高的多放几个数据库,或者用SSD来存储,这样也会快一点。抢购也是,热门的可以专门搞一个数据库或多部署几个数据库,这样也能防止访问量过高导致整个项目崩溃。

3.容灾防灾

容灾防灾也是对数据库的优化,主要是对数据冗余,可能常见的就是日志、备份,定时定期做备份,防止数据丢失,通过日志也可以防止数据库异常,防止数据丢失。我们可以将数据和日志分开,放在不同的磁盘上,这样也是一种方法来进行数据库优化。还有一种备份是主从备份,这种有热备份和冷备份,我们可能听过异地多活,其实这种我们可以把对数据库的操作增加消息,让多个地方来接收消息,这样就可以实现数据同步,达到异地多活的目的。

四、硬件方面

硬件方面也有很多,比如网络带宽、服务器内存、操作系统、CPU还有上面说的SSD固态硬盘等。

五、个人总结

上面列举的可能也不是太全面,毕竟我也不是这方面的专家,对数据库的设计经验可能也不是太多,也只设计过两三个项目而且也都是小的项目,而且上面的每一点如果要深入研究可能又有好多东西要学,都可以单独展开学习,对数据库性能的优化也不是单个方面的,可能上面的各个方面都要用到。这是我在这两天去惠州玩的过程中的一些思考与总结,欢迎各位指点,或者有好的观点也可以多多交流。