V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
JasonLaw
V2EX  ›  程序员

PageHelper-Spring-Boot-Starter 所产生的 count 很耗时间,怎么优化?

  •  
  •   JasonLaw · 2022-03-17 22:47:46 +08:00 · 2030 次点击
    这是一个创建于 986 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个方法是分页获取用户,方法如下:

    PageHelper.startPage(pageNumber, pageSize);
    List<UserPageResponse> userPageResponseList = userMapper.findBy(some condition);
    return new PageInfo<>(userPageResponseList);
    

    userMapper.findBy对应的 SQL 语句如下:

    SELECT u.id,
           u.name,
           total_consumption_times, # 复杂的 count
           total_consumption_amount, # 复杂的 sum
           u.last_consumption_time
    FROM user u
    where ...
    order by u.create_time desc;
    

    我期望它产生的 count 语句是:

    SELECT count(0)
    FROM (SELECT 0
          FROM user u
          where ...) table_count;
    

    但实际它产生的 count 语句如下,导致执行时间很长。

    SELECT count(0)
    FROM (SELECT u.id,
                 u.name,
                 total_consumption_times,  # 复杂的 count
                 total_consumption_amount, # 复杂的 sum
                 u.last_consumption_time
          FROM user u
          where ...) table_count;
    

    怎么解决这个问题?🤕


    一个相关的 issue:1.3.1 版本 count 问题 · Issue #121 · pagehelper/pagehelper-spring-boot

    第 1 条附言  ·  2022-03-18 10:43:12 +08:00

    解决方法:手写 count 查询,具体怎么操作可以查看Mybatis-PageHelper/Changelog.md at master · pagehelper/Mybatis-PageHelper - 5.0.4 - 2017-08-01

    13 条回复    2022-03-18 17:37:19 +08:00
    xiaowei0823
        1
    xiaowei0823  
       2022-03-17 23:27:44 +08:00 via iPhone
    导致时间很长的是 select * 而不是 select count(0) from select 吗?
    taogen
        2
    taogen  
       2022-03-17 23:39:13 +08:00 via Android
    蹲一个答案
    pelloz
        3
    pelloz  
       2022-03-17 23:47:24 +08:00
    像这样的框架问题,你一下没法修复或者换框架,那么你直接自己写一个 count 的 mapper ,先按自己正确的方法获取 count ,然后指定 page 的时候不要 count 就行了。我要是你,就换 mybatis-plus 了...
    xuanbg
        4
    xuanbg  
       2022-03-18 06:44:44 +08:00
    mybatis-plus 也不能解决 PageHelper 的这个 count 问题吧?正确的做法就是在有复杂查询的时候,抛开 PageHelper 自己写一个查询 count 的方法。PageHelper 只用在简单查询上面。
    jorneyr
        5
    jorneyr  
       2022-03-18 06:54:25 +08:00
    我不喜欢用这些插件,都是直接多写一个 SQL 。
    JasonLaw
        6
    JasonLaw  
    OP
       2022-03-18 08:52:14 +08:00
    @xiaowei0823 #1 导致时间很长是因为内嵌的 select 包含复杂的聚合运算。
    JasonLaw
        7
    JasonLaw  
    OP
       2022-03-18 08:54:25 +08:00
    @pelloz #3 MyBatis-Plus 能够解决这个问题?怎么解决的?
    agzou
        8
    agzou  
       2022-03-18 09:24:08 +08:00
    手动分页
    justNoBody
        9
    justNoBody  
       2022-03-18 09:40:55 +08:00   ❤️ 1
    JasonLaw
        10
    JasonLaw  
    OP
       2022-03-18 09:54:43 +08:00
    @justNoBody #9 我刚刚找到了,THX ,准备等一下整理到附言那里。
    JasonLaw
        11
    JasonLaw  
    OP
       2022-03-18 09:56:03 +08:00
    @taogen #2 可以看一下 9 楼 justNoBody 的回复。
    taogen
        12
    taogen  
       2022-03-18 13:19:52 +08:00
    @JasonLaw #11 好的
    silentsky
        13
    silentsky  
       2022-03-18 17:37:19 +08:00
    很简单 不要统计总页数
    PageHelper.startPage(pageNumber, pageSize, Boolean.FALSE);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2500 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 15:56 · PVG 23:56 · LAX 07:56 · JFK 10:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.