一种Oracle数据库分页查询优化思路

针对大数据量(300万条记录含CLOB字段)的分页查询问题,通过调整排序方式和转换分页参数,实现查询速度显著提升。本文分享了在MyBatis中实现这一优化的具体方法。

在项目中需要对一张表进行分页查询,按照常规的分页写法,使用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>

完成后查询速度明显提升,不过有局限性,如果用户想查中间页数的,那速度也会慢,不过这种操作场景基本很少

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值