• PageHelper插件使用Mybatis二级缓存完美解决分页查询慢问题


    项目场景:

    大量数据百万级使用PageHelper进行分页查询时响应速度很慢,加索引后依然无效。


    原因分析:

    想必大家已经做过一些研究和分析,PageHelper分页查询会执行两条SQL语句,一条是count,一条是limit分页,索引添加好后limit会很快这个没有关系,但是count会巨慢


    解决方案:

    1. 从根源上解决问题

    不使用后端count,在PageHelper.start方法中传输一个false,不开启统计,但是这样前端只能做一个假分页
    在这里插入图片描述

    2. 使用自定义统计方法

    PageHelper默认是将查询SQL外包了一层count(0)作为记录总数,count会导致查询很慢,如果我们没有条件查询,只是单纯的分页可以使用重新PageHelper的couunt方法进行执行。

    1. 在mapper.xml文件中,编写一个新的查询方法,命名为要分页的方法+_COUNT
      在这里插入图片描述
    2. 这样查询时就会调用自己写的count方法了,通常count的方法是
      select max(id) 或者explain中的rows作为总数。
      这种方法有个缺点,当输入的有查询条件时会比较麻烦。

    3. 终极大招:使用Mybatis二级缓存

    一级缓存:同一次会话、同一个SQL的查询结果会被缓存,当使用事务管理方法时会启用一级缓存(Mybatis默认打开)。

    二级缓存:不管会话,只要是mapper.xml的同一个方法,只要入参相同就会被缓存起来,下次查询时不再触发查询数据库。默认缓存时间一小时。

    了解过PageHelper原理的朋友就会知道,查询时慢的couunt在自定义参数(条件查询)不变的情况下,其他分页参数不会改变,所以我们可以使用二级缓存对分页查询进行优化。

    开启二级缓存,这里以SpringBoot为例

    1. 加入配置文件
      在这里插入图片描述
      # 开启mybatis的二级缓存
    mybatis:
      configuration:
        cache-enabled: true
    
    1. 将持久化的类实现序列化,就是Mapper中的返回参数那个类
      在这里插入图片描述
    implements Serializable
    
    1. 在Mapper.xml中开启二级缓存,注意这里不要使用注解的方式加在Mapper类上,因为PageHelper会动态代理Mapper,给mapper.xml添加一个count方法,所以只有直接写在mapper.xml配置文件中才会生效。

      在这里插入图片描述
    2. 不想使用二级缓存的方法可以剔除
      在这里插入图片描述
    3. 测试,启动后调用mapper方法,输入相同的参数,在打印日志中搜索Cache Hit,会发现第二次调用缓存命中率变成了0.5,第一次是0,就是没有走缓存了,并且速度明显变快。
    4. 这里只介绍步骤,提供一个思路,大家可以自由的扩展使用,比如在类启动时直接将结果预加载到二级缓存中等。
  • 相关阅读:
    1.JUL
    list容器模拟实现及使用——C++
    antd+react Hook弹窗改进版
    Web自动化测试怎么做?Web自动化测试的详细流程和步骤
    adb突然获取不到华为/荣耀手机。。。
    FS4059A与FS5080E充电芯片的区别
    rv1126-rv1109-yaffs2-mkyaffs2image610
    开放式激光振镜运动控制器(三):ZMC408SCAN轴控光纤激光器加工
    黑马Java笔记第5讲—方法
    深度学习快速入门----Pytorch 系列1
  • 原文地址:https://blog.csdn.net/weixin_43464964/article/details/127036887