针对数据查询缓慢的优化
<a href="#_5">前言</a> <a href="#_11">一、查询效率缓慢原因</a> <a href="#_20">二、解决方案</a> <a href="#_38">总结</a>
<hr>
最近在解决用户反馈的时候发现有些用户查询效率太慢或者直接就查询sql超时(这里配的是默认15秒),然后就在考虑如何在百万级用户的情况下优化性能。
<hr>
Java层面
第一层面是java代码原因,最常见的就是java写了太多的暴力循环(例如多重嵌套for循环),导致时间复杂度太高,就导致后端返回结果的时间过于缓慢,让用户体验十分差。
mysql层面(数据库)
第二层方面就是数据库原因,这里说mysql的情况,最常见的就是有些热数据字段没加索引导致慢查询甚至超时,sql写的不合理各种子查询联表查询,数据库表的设计不合理,还有一种情况是用户的数据量太大(主要原因);
Java层面
1、优化代码:减少不必要的循环,一般我是把某个业务理解透了,在for循环里边进行适当的continue或break关键字减少循环,如果算法比较厉害的人,可以把时间复杂度降到O(n)甚至O(logN),例如查找某个数用二分查找,也可以用递归通过空间换取性能的方式(注意堆栈溢出) 2、异步操作:对某些不需要立马得到结果的数据,可以利用异步操作让用户感觉到加载迅速,先返回一个结果给用户,其余的数据用异步操作。这边可以使用多线程实现异步操作,我发现spring这里是有<font color="red">@Async</font>关键字到方法上实现异步操作,创建线程池和线程都不需要自己担心,多线程的配置可以在配置文件上直接配置即可;还有一种方式是使用消息队列,例如rocketMQ,感兴趣的可以去看看消息队列的相关文章。
数据库层面(mysql)
1、花更多的钱:有土豪式买更多的数据库服务器,提供更多的节点,这样访问压力小的时候查询性能会更高。 2、分库分表:这里分表一般都是水平分表(只根据数据量分),垂直分表的话需要把业务吃的很透,表设计十分合理难度较大,一般可以设定一定的公式进行水平分表,然后对应的用户查询对应的表数据,这样表里面的数据量也比较少,查询性能比较快。 3、表设计:咱们也可以从表设计层面进行优化,例如对热数据字段加索引增加查询效率;或者在一些的查询主表里面加一些冗余字段,减少联表查询,不过加了之后需要在对该表进行新增、修改操作的业务都需要把该冗余字段给补上,需要十分熟悉业务。 4、sql优化:一般都是sql写的不合理导致索引失效然后sql查询超时,最常见的就是减少子查询,子查询会导致生成一个临时表就相当于又查了一次数据,其余的情况可以利用mybaits的标签if test减少联表,但是这个也是需要十分熟悉业务,并且很多时候你不敢改造这些用了多年的sql。 5、缓存:有些重复查询操作,咱们可以直接去缓存里面去拿,这样效率十分高效,公司是使用了redis,但是缓存也需要考虑很多地方,例如缓存击穿,缓存和数据库存放的数据不一致,这是非常致命的问题,一般缓存只能用来一些影响较小但是查询比较多的数据,例如商城的购物车咱们就可以利用缓存,也可以用es做缓存,这种一般都是针对一些列表数据的全文搜索,但这个类似于加冗余字段,各种操作生成的数据都需要同步到es。 6、异步:跟上文的java类似,也是利用消息队列进行异步操作。
<hr>
目前想到的方案就这些,写的比较乱,这里是记载我目前想法,暂时就没有写实例来体现了,大家有更好的方法可以在评论区指出,我会去科普知识补充上去。
本站主要用于日常笔记的记录和生活日志。本站不保证所有内容信息可靠!(大多数文章属于搬运!)如有版权问题,请联系我立即删除:“abcdsjx@126.com”。
QQ: 1164453243
邮箱: abcdsjx@126.com