这两种编码技术之间有什么区别(优点和缺点)?
select * from (
select rownum rnun, * from table where rownum < x
) where rnum > y
select * from (
select * from table
) where rownum < x and x > y
答案 0 :(得分:4)
这两个查询返回不同的行。
这两种查询都不具有确定性。因此,任何查询都不应该在真实系统中使用。
第一个查询似乎至少是尝试生成行窗口(x和y之间的行)。但是,由于没有ORDER BY,因此行的顺序不确定,窗口可能不会达到您想要的效果。
第二个查询返回任意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
但这种效率往往低于分析查询方法。
答案 1 :(得分:0)
除了没有“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&lt; 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
在此步骤之后,您可以看到“计数停止键”,基数仅为99.在我的数据库中,第二个查询的执行时间比第一个快一秒。