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

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

                    
                      ORDER BY L.ID ASC
                    
                )L2
                WHERE ROWNUM  #{bo.endIndex}
            )L3
            WHERE ROW_ID  ]]> #{bo.startIndex}
        ) L4
        /*这个是避免页面展示顺序与原来的不一致*/
        
            ORDER BY L4.ID DESC
        

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

你可能感兴趣的:(SQL)