Câu hỏi này đã được trả lời, tôi sẽ chỉ giải thích tại sao đôi khi bộ lọc ROWNUM =1 hoặc ROWNUM <=1 có thể dẫn đến thời gian phản hồi lâu.
Khi gặp bộ lọc ROWNUM (trên một bảng), trình tối ưu hóa sẽ tạo ra một QUÉT ĐẦY ĐỦ với COUNT STOPKEY. Điều này có nghĩa là Oracle sẽ bắt đầu đọc các hàng cho đến khi nó gặp N hàng đầu tiên (ở đây là N =1). Quá trình quét toàn bộ đọc các khối từ mức đầu tiên đến mốc nước cao. Oracle không có cách nào để xác định khối nào chứa hàng và khối nào không chứa trước, do đó tất cả các khối sẽ được đọc cho đến khi tìm thấy N hàng. Nếu các khối đầu tiên trống, nó có thể dẫn đến nhiều lần đọc.
Hãy xem xét những điều sau:
Các hàngSQL> /* rows will take a lot of space because of the CHAR column */
SQL> create table example (id number, fill char(2000));
Table created
SQL> insert into example
2 select rownum, 'x' from all_objects where rownum <= 100000;
100000 rows inserted
SQL> commit;
Commit complete
SQL> delete from example where id <= 99000;
99000 rows deleted
SQL> set timing on
SQL> set autotrace traceonly
SQL> select * from example where rownum = 1;
Elapsed: 00:00:05.01
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=1 Bytes=2015)
1 0 COUNT (STOPKEY)
2 1 TABLE ACCESS (FULL) OF 'EXAMPLE' (TABLE) (Cost=7 Card=1588 [..])
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
33211 consistent gets
25901 physical reads
0 redo size
2237 bytes sent via SQL*Net to client
278 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Như bạn có thể thấy, số lượng hàng quán đạt được là rất cao (đối với một hàng duy nhất). Tình huống này có thể gặp phải trong một số trường hợp, ví dụ:bạn chèn các hàng bằng /*+APPEND*/
gợi ý (do đó trên vạch nước cao) và bạn cũng xóa các hàng cũ nhất theo định kỳ, dẫn đến nhiều khoảng trống ở đầu đoạn.