繁体   English   中英

Oracle Rownum SQL

[英]Oracle Rownum SQL

这两种编码技术之间有什么区别(优点和缺点)?

select * from (
    select rownum rnun, * from table where rownum < x
) where rnum > y


select * from (
    select * from table
) where rownum < x and x > y

这两个查询返回不同的行。

这两个查询都不是确定性的。 因此,任何查询都不应该在实际系统中使用。

第一个查询似乎至少是尝试生成行(x 和 y 之间的行)的 window。 但是,由于没有 ORDER BY,因此行的顺序不是确定性的,并且 window 可能无法满足您的要求。

第二个查询返回任意 x 行数据(假设 x > y)。 否则返回 0 行(如果 y >= x)。 如果您正在尝试构建某种窗口查询,则不是这样。

如果你想要一个有效的窗口查询,你会想要类似的东西

SELECT *
  FROM (SELECT a.*,
               row_number() over (order by something) rnum
          FROM table_name)
 WHERE rnum BETWEEN x AND y

如果你想使用 ROWNUM,你需要类似的东西

SELECT *
  FROM (SELECT a.*,
               rownum rnum
          FROM( SELECT b.*
                  FROM table_name
                 ORDER BY something) a)
 WHERE rownum < y
   AND rnum > x

但这往往比分析查询方法效率低。

除了没有“order by”条款之外……问题可能是关于 Oracle STOPKEY 功能? 在“分页”查询的情况下,Oracle 可以使用 STOPKEY 功能来限制子查询中的行数,这可能会带来一些性能提升。

看看这个查询:

select *
  from (select a.*,
               row_number() over (order by sname) rnum
          from t_patient_card a)
 where rnum between 1 and 100           

                                                        Cost    Cardinality

SELECT STATEMENT, GOAL = FIRST_ROWS                     313272  3571266
 VIEW        HOSPITAL2$                                 313272  3571266
  SORT ORDER BY                                         313272  3571266
   COUNT
  TABLE ACCESS FULL    HOSPITAL2$    T_PATIENT_CARD     38883   3571266

Oracle 之前获取的所有行只返回其中的 100 个

让我们像这样重写查询:

select *
  from (
  select rownum as rn,tt.*  from  
  (
   select  t.* from t_patient_card t order by  t.sname
  )tt where rownum<100       
    ) 
 WHERE rn >1

在这种情况下,我们在子查询中使用 rownum<100 来通知优化器我们想要减少 100 行。

                                                        Cost    Cardinality
SELECT STATEMENT, GOAL = ALL_ROWS                       313272  99
 VIEW    HOSPITAL2$                                     313272  99
  COUNT STOPKEY
   VIEW    HOSPITAL2$                                   313272  3571266
    SORT ORDER BY STOPKEY                               313272  3571266
  TABLE ACCESS FULL    HOSPITAL2$    T_PATIENT_CARD     38883   3571266

在这一步之后,您可以看到“count stopkey”和基数只有 99。在我的数据库中,第二个查询的执行速度比第一个查询快一秒。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM