使用 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的性能