`
jimmy9495
  • 浏览: 299062 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

oracle分页查询不用order by排序速度反而变慢问题分析总结

阅读更多
--sql-1,不使用order by排序再分页,执行300多秒才出来:
select *
  from (select t.*, rownum rn
          from (select a.RFID,
                       decode(e.type, '112', e.name, sh.name) as name,
                       to_char(d.DEATH_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       to_char(d.DEATH_DEAL_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_TAG,
                       d.DEATH_TYPE,
                       to_char(d.DEATH_REG_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_RESULT,
                       d.DEATH_REASON,
                       d.death_change,
                       d.death_method,
                       d.id /* ,
                            rownum as ro    */
                  from tbl_Death       d,
                       tbl_animal_info a,
                       tbl_Enterprise  e,
                       tbl_Enterprise  sh,
                       tbl_Region      r
                 where d.ANIMAL_ID = a.id
                   and a.ENTERPRISE_ID = e.id(+)
                   and a.owner_name = to_char(sh.id(+))
                   and e.REGION_ID = r.id
                   and r.code like '331082%'
                --order by d.id desc   
                ) t
         where rownum <= 20) re
 where re.rn >= 1


sql-1第一次执行了300多秒才出来,第二次17秒,第三次12秒。
sql-1执行计划:(可以看到cost消耗很小,cardinality基数很大)


--sql-2,使用order by排序再分页,1秒左右出来:
select *
  from (select t.*, rownum rn
          from (select a.RFID,
                       decode(e.type, '112', e.name, sh.name) as name,
                       to_char(d.DEATH_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       to_char(d.DEATH_DEAL_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_TAG,
                       d.DEATH_TYPE,
                       to_char(d.DEATH_REG_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_RESULT,
                       d.DEATH_REASON,
                       d.death_change,
                       d.death_method,
                       d.id /* ,
                            rownum as ro    */
                  from tbl_Death       d,
                       tbl_animal_info a,
                       tbl_Enterprise  e,
                       tbl_Enterprise  sh,
                       tbl_Region      r
                 where d.ANIMAL_ID = a.id
                   and a.ENTERPRISE_ID = e.id(+)
                   and a.owner_name = to_char(sh.id(+))
                   and e.REGION_ID = r.id
                   and r.code like '331082%'
                 order by d.id desc) t
         where rownum <= 20) re
 where re.rn >= 1


sql-2第一次执行3.2秒,后面都是0.4秒内就出来了。
sql-2执行计划:(可以看到cost消耗较小,cardinality基数变很小了)



以前看执行计划,以为只要看cost消耗小,sql就会执行很快,现在看来cardinality基数的影响也是很大的。

--sql-3 是sql-1不分页,内层的sql,执行很快1秒内。
select a.RFID,
                       decode(e.type, '112', e.name, sh.name) as name,
                       to_char(d.DEATH_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       to_char(d.DEATH_DEAL_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_TAG,
                       d.DEATH_TYPE,
                       to_char(d.DEATH_REG_DATE, 'yyyy-mm-dd hh24:mi:ss'),
                       d.DEATH_DEAL_RESULT,
                       d.DEATH_REASON,
                       d.death_change,
                       d.death_method,
                       d.id /* ,
                            rownum as ro    */
                  from tbl_Death       d,
                       tbl_animal_info a,
                       tbl_Enterprise  e,
                       tbl_Enterprise  sh,
                       tbl_Region      r
                 where d.ANIMAL_ID = a.id
                   and a.ENTERPRISE_ID = e.id(+)
                   and a.owner_name = to_char(sh.id(+))
                   and e.REGION_ID = r.id
                   and r.code like '331082%'


sql-3执行速度基本和sql-2一样。
sql-3执行计划:(可以看到cost消耗和cardinality基数,基本和排序了的sql-2在一个数量级)



总结分析:不用order by排序而分页,oracle需要耗费更多来记住这个无序的排序,以用以分页。而已经按索引列排序的字段order by后,减少了这个过程。所以使用order by反而加快了实际查询速度。

ps:有高手看到的话希望能提点一下:sql-1第一次执行300多秒,后面接着执行几次变成了10秒多出来,这是oracle的什么缓存机制吗?想知道具体是oracle的什么样的原理机制。这也是线上系统经常遇到的一个问题,第一次点sql执行太久,不出结果,过一会再点就可以了。
  • 大小: 77.1 KB
  • 大小: 83.4 KB
  • 大小: 67.5 KB
分享到:
评论

相关推荐

    Oracle&JSP分页和Oracle分页

    在处理大量数据时,分页功能变得尤为关键,因为它能够有效地提高用户体验,避免一次性加载过多数据导致页面响应速度变慢。本文将详细讲解如何在Oracle数据库中进行分页查询,并结合JSP实现前端展示。 首先,了解...

    分页代码Oracle

    在Oracle数据库中,分页查询是一项非常常见的操作,特别是在数据量庞大的情况下,为了提高用户体验,避免一次性加载过多数据导致页面响应变慢,我们通常会采用分页的方式展示数据。本篇将详细介绍Oracle数据库中的...

    Oracle分页技术(txt文档)

    Oracle数据库在处理大数据量时,分页查询是一种非常常见的优化策略,它可以帮助用户逐步加载数据,提高用户体验,同时减轻服务器的负担。这篇博客主要探讨了Oracle数据库中的分页技术,结合源码和实用工具,提供了...

    mysql,oracle,sqlserver分页

    - 需要注意的是,这种方法随着查询范围的扩大,执行速度可能会变慢。 #### SQL Server 分页 SQL Server 提供了多种方式进行分页查询,其中比较常用的方法是使用`ROW_NUMBER()`窗口函数。 1. **数据准备**: - ...

    15oracle的PL/SQL编程-分页 PPT

    总结,Oracle的PL/SQL编程中的分页技术是数据库管理的重要组成部分,通过合理使用`ROWNUM`、窗口函数以及`OFFSET/FETCH`等方法,可以有效地实现高效且灵活的分页查询,同时优化系统性能,提升用户体验。

    Oracle复习总结

    它们可以加快SELECT、UPDATE和DELETE的速度,但INSERT操作可能会变慢。索引通过减少磁盘I/O提升查询性能,但并非所有查询都适合使用索引。 8. **索引与查询性能**:索引不总是能提高查询性能,如果查询不使用索引或...

    仿orm自动生成分页SQL分享

    在处理大量数据时,分页查询是非常常见的需求,它能有效地提高用户体验,避免一次性加载过多数据导致页面响应变慢。 本文主要探讨了在不同数据库系统中如何自动生成分页SQL,包括SQL Server 2000至2008、Oracle和...

    数据库真分页SQL语句

    - **索引策略**:确保用于分页的关键字有合适的索引,可以极大地提升查询速度。主键或唯一标识通常具有良好的索引性能。 - **避免全表扫描**:使用WHERE子句过滤不必要的数据,减少扫描的行数。 - **避免使用...

    SQL自动分页

    在网页应用中,为了处理大量数据,通常需要使用分页技术来提高用户体验,避免一次性加载过多数据导致页面响应变慢。SQL自动分页是一种优化数据查询的方法,它使得开发人员能够轻松地实现数据的分页展示,同时确保...

    oracle SQL语法大全

    1. 索引:正确创建和使用索引能显著提升查询速度,但过度索引可能导致写操作变慢。 2. EXPLAIN PLAN:分析SQL执行计划,帮助理解查询如何在数据库中执行并找出性能瓶颈。 3.绑定变量:使用绑定变量可以避免SQL解析...

    数据库分页

    - **使用索引**:确保用于排序的列有合适的索引,以加快查询速度。没有索引,分页查询可能变得极其慢。 - **避免全表扫描**:OFFSET在大数据量下性能较差,因为它需要扫描从第一页到当前页的所有记录。可以尝试使用`...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...

    精妙Sql语句

    6. **分页查询**:LIMIT和OFFSET子句在MySQL中用于实现分页,而在SQL Server中可以使用TOP和WITH TIES配合ORDER BY来实现类似功能。 7. **窗口函数**:如ROW_NUMBER()、RANK()、DENSE_RANK()、LEAD()、LAG()等,...

    数据库面试题.docx

    首先连接表,然后应用 WHERE 条件过滤行,接着按 GROUP BY 进行分组,HAVING 用于在分组后过滤,SELECT 用于指定选择的列,最后 ORDER BY 对结果进行排序。 以上是面试中常见的数据库相关知识点,涵盖了 MySQL 和 ...

    阿里巴巴笔试题及答案.pdf

    - **影响DML操作**: 插入、更新、删除操作可能会因为维护索引而变慢。 #### 七、索引与性能的关系 虽然索引通常能提高查询性能,但在某些情况下可能并不会显著提升性能,甚至会降低性能。这取决于多种因素,如索引...

    java工程师面试题大全-100%公司笔试题你都能碰到几个.pdf

    **Oracle分页**: 1. **截取ID法**: ```sql SELECT * FROM ( SELECT emp.*, ROWNUM AS num FROM emp ) WHERE num BETWEEN 5 AND 7; ``` 2. **三层嵌套法**: ```sql SELECT * FROM ( SELECT a.*, ROWNUM r ...

Global site tag (gtag.js) - Google Analytics