如何做查询优化
缓存
对于经常访问的数据,可以通过使用缓存来提高查询性能,降低数据库压力
场景:
1.高频访问的数据:如系统首页、热门推荐内容等。
2.计算成本较高的数据:如复杂查询结果、大量数据的统计结果.
3.允许短时间延迟的数据:如不需要实时更新的排行榜、图片列表等。
本项目中的主页数据就可以使用缓存来优化
Redis分布式缓存
这里我们要对接口数据进行缓存
key设计:可以采用 项目名:接口名:查询条件的格式进行命名例如:dongpicture:listPictureVOByPage:${查询条件key}
value设计:一种是json,一种是二进制
过期事件:根据业务来定,这里可以设置为5-60分钟
操作
jedis
spring data redis
caffine 本地缓存
当应用需要频繁访问某些数据时,可以将这些数据缓存到应用的内存中(比如JVM中);下次访问时,
直接从内存读取,而不需要经过网络或其他存储系统。
相比于分布式缓存,本地缓存的速度更快,但是无法在多个服多器间共享数据、而且不方便扩容。
所以本地缓存的应用场景一般是:
-
数据访问量有限的小型数据集
-
不需要服务器间共享数据的单机应用
-
高频、低延迟的访问场景(如用户临时会话信息、短期热点数据)。
-
对于Java项目,Caffeine是主流的本地缓存技术,拥有极高的性能和丰富的功能。比如可以精确控制
缓存数量和大小、支持缓存过期、支持多种缓存淘汰策略、支持异步操作、线程安全等。
由于本地缓存不需要引入额外的中间件,成本更低。因此如果只是要提升数据访问性能,优先考虑本地缓存而不是分布式缓存。
多级缓存
多级缓存是指结合本地缓存和分布式缓存的优点,在同一业务场景下构建两级缓存系统,这样可以兼顾
本地缓存的高性能、以及分布式缓存的数据一致性和可靠性。
多级缓存的工作流程:
1.第一级(Caffeine本地缓存):优先从本地缓存中读取数据。如果命中,则直接返回。
2.第二级(Redis分布式缓存):如果本地缓存未命中,则查询PRedis分布式缓存。如果Redis命
中,则返回数据并更新本地缓存。
3.数据库查询:如果Redis也未命中,则查询数据库,并将结果写入Redis和本地缓存
手动缓存
提供一个接口,可以让管理员来手动触发更新缓存
扩展-缓存使用问题
击穿
缓存击穿:某些热点数据在缓存过期后,大量请求直接打到数据库
解决方案:
- 设置热点数据的超长过期时间,
- 或使用互斥锁(如Redissorn)控制缓存刷新。
穿透
缓存穿透:用户频繁请求不存在的数据,导致大量的请求直接子触发数据库查询
解决方案:
- 对无效查询结果也进行缓存(如设置空值缓存),
- 或者使用布隆过滤器。
雪崩
缓存雪崩:大量缓存同时过期,导致请求打到数据库,系统崩溃。
解决方案:
- 设置不同缓存的过期时间,避免同时过期;
- 或者使用多级缓存,减少对数据库的依赖。
扩展-自动识别热点数据
如果要引入第三方,就可以借助京东的hotkey来实现
如果自己开发,可以通过计数器的方式,自动进行识别存储缓存