在项目中需要对一张表进行分页查询,按照常规的分页写法,使用ROWNUM实现了分页,但是随着数据的不断增加,目前达到300万条,并且有CLOB字段,在查询后几页数据时,直接超时。
SELECT L4.ID, L4.EXECUTE_TIME FROM
( SELECT * FROM
( SELECT L2.*,ROWNUM ROW_ID FROM
(SELECT * from TABLE1 L ORDER BY L.ID DESC )L2
WHERE ROWNUM <= 3289360 )L3
WHERE ROW_ID > 3289350 ) L4
这种是肯定需要解决的,没百度(没钱上VPN找Google)到理想的解决方案。
下午想到在查询前几页的速度很快,此时的排序时根据ID(物理主键)降序排列,如果将主键升序排列,那也会很快。
因此在mybatis插入分页参数前,需要对下标及偏移量进行转换。
int mod = total % pageSize;
int compensation = mod == 0 ? 0 : (pageSize - mod);
startIndex = (totalPages - currentPage) * pageSize - compensation;
endIndex = (totalPages - currentPage + 1) * pageSize - compensation;
其中对于当前页在后半部分,并且条数超过某某条,ID就走升序排列,以下是mybatis的主要逻辑部分
SELECT
L4.ID,
L4.EXECUTE_TIME
FROM
(
SELECT *
FROM (
SELECT L2.*,ROWNUM ROW_ID
FROM
(
SELECT L.* from TABLE1 L
<if test="bo.reverseIndex != 1">
ORDER BY L.ID DESC
</if>
<if test="bo.reverseIndex == 1">
ORDER BY L.ID ASC
</if>
)L2
WHERE ROWNUM <![CDATA[ <= ]]> #{bo.endIndex}
)L3
WHERE ROW_ID <![CDATA[ > ]]> #{bo.startIndex}
) L4
/*这个是避免页面展示顺序与原来的不一致*/
<if test="bo.reverseIndex == 1">
ORDER BY L4.ID DESC
</if>
完成后查询速度明显提升,不过有局限性,如果用户想查中间页数的,那速度也会慢,不过这种操作场景基本很少
针对大数据量(300万条记录含CLOB字段)的分页查询问题,通过调整排序方式和转换分页参数,实现查询速度显著提升。本文分享了在MyBatis中实现这一优化的具体方法。
774

被折叠的 条评论
为什么被折叠?



