What are the differences (advantages and disadvantages) between these two coding techniques?
select * from (
select rownum rnun, * from table where rownum < x
) where rnum > y
select * from (
select * from table
) where rownum < x and x &g开发者_如何学编程t; y
The two queries return different rows.
Neither query is deterministic. So neither query should ever be used in a real system.
The first query appears to be at least an attempt to generate a window of rows (rows between x and y). Since there is no ORDER BY, however, the order of rows is not deterministic and the window probably doesn't do what you want.
The second query returns an arbitrary x rows of data (assuming x > y). Otherwise it returns 0 rows (if y >= x). If you're trying to build some sort of windowing query, this isn't it.
If you want a windowing query that works, you'd want something like
SELECT *
FROM (SELECT a.*,
row_number() over (order by something) rnum
FROM table_name)
WHERE rnum BETWEEN x AND y
If you wanted to use ROWNUM, you'd need something like
SELECT *
FROM (SELECT a.*,
rownum rnum
FROM( SELECT b.*
FROM table_name
ORDER BY something) a)
WHERE rownum < y
AND rnum > x
But this tends to be less efficient than the analytic query approach.
Besides the absence of the “order by” clause….. May be the question is about Oracle STOPKEY feature? In case of “paging” queries Oracle can use a STOPKEY feature to limit the number of rows in the subquery, this can lead to some performance gain.
Look at this query:
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 fetched all the rows before is return only 100 of them
Let’s rewrite the query like this:
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
In this case we user rownum<100 in the subquery to inform the optimizer that we want to get less the 100 rows.
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
You can see the “count stopkey” and cardinality is only 99 after this step.In my database the second query executes one second faster then the first one.
精彩评论