mybatisplus.BaseMapper#selectPage 使用方法

使用 com.baomidou.mybatisplus.mapper.BaseMapper#selectPage 方法查询分页列表时,在mysql层面会执行两条sql,一条是count,另一条才是获取分页数据,大部分场景下我们都可以直接使用这个方法来进行查询,但是一些特殊场景下这个获取总数的sql会比获取分页数据执行的耗时更高。

列子

1.count 查询

sql 复制代码
    SELECT 
        user_identifier, 
        transaction_date, 
        monetary_unit, 
        SUM(incoming_value) AS total_incoming, 
        SUM(ABS(outgoing_value)) AS total_outgoing, 
        SUM(closing_value) AS total_balance 
    FROM 
        financial_records_summary 
    WHERE 
        user_identifier = ? 
        AND transaction_date >= ? 
        AND transaction_date <= ? 
    GROUP BY 
        user_identifier, transaction_date, monetary_unit 
    ORDER BY 
        transaction_date DESC, 
        monetary_unit, 
        total_balance DESC
) AS aggregated_results

2.分页信息查询

sql 复制代码
SELECT 
    user_identifier, 
    transaction_date, 
    monetary_unit, 
    SUM(incoming_value) AS total_incoming, 
    SUM(ABS(outgoing_value)) AS total_outgoing, 
    SUM(closing_value) AS total_balance 
FROM 
    financial_records_summary 
WHERE 
    account_owner = ? 
    AND transaction_date >= ? 
    AND transaction_date <= ? 
GROUP BY 
    user_identifier, 
    transaction_date, 
    monetary_unit 
ORDER BY 
    transaction_date DESC, 
    monetary_unit, 
    total_balance DESC 
LIMIT 0, 10

当数据量足够大的时候,第一个sql查询耗时是第二个sql查询耗时的两倍多,原因主要是以下几点:

  • COUNT需要处理全部结果集
  • 数据查询有LIMIT限制可能提前终止
  • 子查询中的ORDER BY对COUNT来说是多余开销

通过移除不必要的操作可以大幅度优化这个sql的性能