查询太慢怎么办——加缓存啊

查询太慢怎么办——加缓存啊,第1张

查询太慢怎么办——加缓存啊 前言

很多朋友可能会遇到数据量比较大的时候,你的接口查询特别慢。如果是这样的话,处理的方案特别多,比如将你的串行查询改成并行查询、优化sql、加索引、最后实在没办法了,去加缓存。因为缓存会导致缓存的数据与数据库的数据不一样的情况。所以,不要什么都加缓存。看情况而定。

缓存介绍

其实加缓存的方法有很多种,比如说利用redis作为缓存、利用spring自己提供的缓存机制进行缓存、还有二级缓存。下面我会全部说说怎么使用这些东西。
缓存使用方法:

  1. 使用redis进行缓存,查看redis与springboot整合使用缓存
  2. 使用hutool工具进行缓存,要求jdk1.8+
    导入maven依赖

      cn.hutool
       hutool-all
       5.5.2

使用代码

@Service
@Slf4j
public class SyjkServiceImpl implements SyjkService {

    public static final String hyyc = "HYYCQK";
    public static final String paramcheck = "PARAM_CHECK";
    @Resource
    private SyjkMapper syjkMapper;
    @Resource
    private CommonMapper commonMapper;
    private static Cache> cache = CacheUtil.newTimedCache(600000);

  
    @Override
    public List getHyycqk(baseDto baseDto) {
        //获取缓存中的数据
        List hyycqkVos = cache.get(hyyc);
        baseDto baseDto1 = paraCache.get(paramcheck);
        if (hyycqkVos == null && baseDto1 == null) {
            return getHyycqkBySjk(baseDto);
        }else if(!StringUtils.equals(baseDto1.getSwjgId(), baseDto.getSwjgId()) || !StringUtils.equals(baseDto1.getSsnd(), baseDto.getSsnd())) {
            return getHyycqkBySjk(baseDto);
        }
        return hyycqkVos;
    }
}

  1. 上面的效率不是最高的,最高的是二级缓存,这个是基于内存的缓存,目前使用比较多的内存缓存框架有guava、Ehcache、caffine等。
    我们以spring官方提供的caffine为例。
    导入jar包

    org.springframework.boot
    spring-boot-starter-cache


    com.github.ben-manes.caffeine
    caffeine
    2.6.0

配置CacheManager,开启EnableCaching

@Configuration
@EnableCaching
public class CacheConfig {
    @Bean
    public CacheManager cacheManager(){
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        //Caffeine配置
        Caffeine caffeine = Caffeine.newBuilder()
                //最后一次写入后经过固定时间过期
                .expireAfterWrite(10, TimeUnit.SECONDS)
                //缓存的最大条数
                .maximumSize(1000);
        cacheManager.setCaffeine(caffeine);
        return cacheManager;
    }
}

其实不想这样写的,也可以这样写


        
    
    
    

使用代码

    @Cacheable(value="myCache",key = "#baseDto+'getSssr'")
    public List getSssr(baseDto baseDto) {
        String cjBySwjg = commonMapper.getCjBySwjg(baseDto.getSwjgId());
        //设置查询参数
        QueryParam queryParam = ParamsDealUtil.setQueryParam(baseDto);
        queryParam.setSwjgcj(cjBySwjg);
        List sssr = qjzsMapper.getSssr(queryParam);
        if(sssr!=null){
            for (SssrVo sssrVo1 : sssr) {
                //处理月份
                SssrVo sssrVo = DealYfUtil.dealYf(sssrVo1);
                if(sssrVo.getQnss()!=null&&sssrVo.getBnss()!=null){
                    sssrVo.setSstb(DoubleUtil.round(((sssrVo.getBnss()- sssrVo.getQnss())/(double)sssrVo.getQnss())*100,1));
                }
            }
        }
        return sssr;
    }

解释一下这个代码的流程:首先当调用我们这个方法的时候,它首先会从caffine缓存种去获取数据,如果能获取到就获取,然后就直接返回数据了,如果获取不到如何就会走方法体烈面的查询语句了,查到数据后会自动重新放到缓存中。

@Cacheable介绍:
value是指你缓存放入的名字,是在放哪里了,key就是指,你根据这个key指获取缓存区域中那个键,是与值一一对应的,不要重复,如果调用这个方法的时候,如果值key不一样了,就不会走缓存,如果一样了就会走缓存了。

其实这个方案是最基础的,通常我们可以这样做(伪代码)

  @Cacheable(value="myCache",key = "#baseDto+'getSssr'")
    public List getSssr(baseDto baseDto) {
      //从redis缓存中获取数据
     Object name = redisTemplate.boundValueOps("name").get();
     if(name==null){
     //从数据库中获取
     List sss=mapper.select(baseDto);
     //放入缓存中
      redisTemplate.boundValueOps("name").set(sss);
     }
      
    }

总结

前面就已经说过了缓存会导致数据不一样的情况,通常用于数据不敏感的查询当中,我们为了解决这种不一致的问题,通常采用的方法是加入定时任务,实时的将我们需要的数据搞进来。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5671566.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存