关于分页查询的优化思路

简介: 目前在生产环境中有一个sql语句执行时间长达7分钟,而且执行频率极高。 其中PROC_INST中有将近6千万的数据。其中STEP_INST是一个物化视图,里面还有5千多条数据。
目前在生产环境中有一个sql语句执行时间长达7分钟,而且执行频率极高。
其中PROC_INST中有将近6千万的数据。其中STEP_INST是一个物化视图,里面还有5千多条数据。
可以看到这个语句已经有了一些调优的痕迹,可以从里面的子查询和hint能够看出一些信息。
SELECT PROC_INST.OBJID, PROC_INST.CREATION_TIME
  FROM PROC_INST,
       (SELECT / * +leading(PROC_INST LIST table_bpm_step_inst)
          FULL(PROC_INST) hash_aj(LIST) use_nl(table_bpm_step_inst) * /
          PROC_INST.OBJID, PROC_INST.CREATION_TIME, ROW_NUMBER() OVER(ORDER BY creation_time) rn
          FROM PROC_INST,
               (SELECT / * +materialize
                  FULL(in_step) PARALLEL(in_step, 8) * / in_step.root2proc_inst
                  FROM STEP_INST in_step
                 WHERE in_step.status NOT IN (?)
                    OR in_step.WAIT_TIME IS NOT NULL) LIST,
               STEP_INST
         WHERE STEP_INST.ROOT2PROC_INST =
               PROC_INST.OBJID
           AND PROC_INST.ROOT_STATUS = ?
           AND PROC_INST.STATUS = ?
           AND STEP_INST.OBJID =
               PROC_INST.BEGIN2STEP_INST
           AND STEP_INST.COMMITTER = ?
           AND STEP_INST.STATUS IN (?)
           AND STEP_INST.WAIT_TIME IS NULL
           AND STEP_INST.ASSIGNEE = ?
           AND PROC_INST.OBJID = list.root2proc_inst(+)
           AND list.root2proc_inst IS NULL
         ORDER BY CREATION_TIME) INNER_QRY
 WHERE INNER_QRY.OBJID = PROC_INST.OBJID
   AND INNER_QRY.rn > ?
   AND INNER_QRY.rn


上面的查询有几个地方需要注意
首先是分析函数row_number的使用。其实在大量的数据查询中直接使用rownum要高效一些,而且在子查询的结果又加了一层order by的排序操作,所以可以考虑去除row_number()
关于AND list.root2proc_inst IS NULL的查询条件,如果看得仔细一点就会发现,这个过滤条件完全可以放在子查询list里面,尽可能排除较多的数据。
子查询的输出结果集PROC_INST.OBJID, PROC_INST.CREATION_TIME,可以考虑直接使用rowid来代替对应的字段值,这样可能对于索引来说就可以是的索引的使用更加高效,如果是range scan就可以从某种程度上提升为fast scan.
最后的这个地方看似没有问题,其实是最需要做改进的地方。如果输出1000~2000行的数据,那么子查询就会先得查出2000条数据。
 AND INNER_QRY.rn > ?
   AND INNER_QRY.rn
如果输出100000~101000 这样的话,就得先得到101000行的数据,然后再排除过滤。这样的话每个查询的执行代价都会不同,可以考虑在回表的数据上进行一个统一的规划。
基本思路就是先在order by之后的子查询之后做一个rownum  然后只输出rowid。再上一层的子查询中继续拍段rownum>? 这样基于rowid的排除更加清晰。

改进之后的sql语句类似下面的样子。
SELECT PROC_INST.OBJID, PROC_INST.CREATION_TIME
  FROM PROC_INST where rid in (
       (SELECT / * +leading(PROC_INST LIST table_bpm_step_inst)
          FULL(PROC_INST) hash_aj(LIST) use_nl(table_bpm_step_inst) * /
          rid
          FROM
          (select rowid rid,rownum rn  from
          (select PROC_INST.rowid from
               PROC_INST,
               (SELECT / * +materialize
                  FULL(in_step) PARALLEL(in_step, 8) * / in_step.root2proc_inst
                  FROM STEP_INST in_step
                 WHERE in_step.status NOT IN (?)
                    OR in_step.WAIT_TIME IS NOT NULL 
                  AND list.root2proc_inst IS NULL) LIST,
               STEP_INST
         WHERE STEP_INST.ROOT2PROC_INST =
               PROC_INST.OBJID
           AND PROC_INST.ROOT_STATUS = ?
           AND PROC_INST.STATUS = ?
           AND STEP_INST.OBJID =
               PROC_INST.BEGIN2STEP_INST
           AND STEP_INST.COMMITTER = ?
           AND STEP_INST.STATUS IN (?)
           AND STEP_INST.WAIT_TIME IS NULL
           AND STEP_INST.ASSIGNEE = ?
           AND PROC_INST.OBJID = list.root2proc_inst(+)
         ORDER BY CREATION_TIME) INNER_QRY
         where rownum)
   AND INNER_QRY.rn >= ?)

最后优化的结果稍后奉上。
目录
相关文章
|
12月前
|
运维 监控 数据可视化
贝锐蒲公英视频监控方案用户答疑:4G/5G入网,没有公网IP也能用
贝锐蒲公英提供创新的视频监控解决方案,适用于多种监控场景,无需依赖专网或公网IP,支持4G/5G网络,实现快速部署与高质量传输。其云端配置平台简化操作流程,具备二层组网与弱网优化功能,确保视频传输流畅。蒲公英还支持多品牌设备集中管理,提供专业级技术支持,适用于有无公网IP环境,确保远程监控高效稳定。
270 4
|
移动开发 小程序 API
uniapp中uview组件库丰富的CountTo 数字滚动使用方法
uniapp中uview组件库丰富的CountTo 数字滚动使用方法
258 2
|
Windows 网络安全 数据安全/隐私保护
|
存储 SQL 弹性计算
走进开源大数据平台 EMR | 学习笔记
快速学习走进开源大数据平台 EMR
走进开源大数据平台 EMR | 学习笔记
|
JSON 前端开发 算法
防止数据抓包窃取
防止数据抓包窃取
721 0
|
设计模式 SpringCloudAlibaba 安全
聊一聊 ReentrantLock 和 AQS 那点事
聊一聊 ReentrantLock 和 AQS 那点事
351 0
聊一聊 ReentrantLock 和 AQS 那点事
|
人工智能 达摩院 机器人
2022十大科技趋势来了!达摩院最新发布
12月28日,阿里巴巴达摩院发布2022十大科技趋势,这是达摩院连续第四年发布前沿科技趋势预测。 达摩院分析了近三年来的770万篇公开论文、8.5万份专利,覆盖159个领域,挖掘其中热点及重点技术突破,深度访谈近100位科学家,提出了2022年可能照进现实的十大科技趋势,覆盖人工智能、芯片、计算和通信等领域。
2022十大科技趋势来了!达摩院最新发布
|
设计模式 缓存 安全
java多线程并发系列--基础知识点(笔试、面试必备)(下)
多个线程间锁的并发控制,对象锁多个线程、每个线程持有该方法所属对象的锁以及类锁。synchronized, wait, notify 是任何对象都具有的同步工具
301 0
java多线程并发系列--基础知识点(笔试、面试必备)(下)
|
Apache
Apache Doris Sequence介绍及使用方法
Sequence列目前只支持Uniq模型,Uniq模型主要针对需要唯一主键的场景,可以保证主键唯一性约束,但是由于使用REPLACE聚合方式,在同一批次中导入的数据,替换顺序不做保证。替换顺序无法保证则无法确定最终导入到表中的具体数据,存在了不确定性。 为了解决这个问题,Doris支持了sequence列,通过用户在导入时指定sequence列,相同key列下,REPLACE聚合类型的列将按照sequence列的值进行替换,较大值可以替换较小值,反之则无法替换。该方法将顺序的确定交给了用户,由用户控制替换顺序。
598 0
Apache Doris Sequence介绍及使用方法
|
弹性计算 运维 安全
云钉一体加速,阿里云计算巢与钉钉深度融合、共建应用新生态
云合计划再升级,“云钉一体”战略按下加速键
云钉一体加速,阿里云计算巢与钉钉深度融合、共建应用新生态