ROW_NUMBER
cukup tidak efisien dalam Oracle
.
Lihat artikel di blog saya untuk detail performa:
- Oracle:ROW_NUMBER vs ROWNUM
Untuk kueri spesifik Anda, saya sarankan Anda menggantinya dengan ROWNUM
dan pastikan indeks yang digunakan:
SELECT *
FROM (
SELECT /*+ INDEX_ASC(t index_on_column) NOPARALLEL_INDEX(t index_on_column) */
t.*, ROWNUM AS rn
FROM table t
ORDER BY
column
)
WHERE rn >= :start
AND rownum <= :end - :start + 1
Kueri ini akan menggunakan COUNT STOPKEY
Pastikan juga Anda column
tidak dapat dibatalkan, atau tambahkan WHERE column IS NOT NULL
kondisi.
Jika tidak, indeks tidak dapat digunakan untuk mengambil semua nilai.
Perhatikan bahwa Anda tidak dapat menggunakan ROWNUM BETWEEN :start and :end
tanpa subkueri.
ROWNUM
selalu ditetapkan terakhir dan diperiksa terakhir, begitulah ROWNUM
selalu berurutan tanpa celah.
Jika Anda menggunakan ROWNUM BETWEEN 10 and 20
, baris pertama yang memenuhi semua ketentuan lainnya akan menjadi kandidat untuk kembali, sementara ditetapkan dengan ROWNUM = 1
dan gagal dalam ujian ROWNUM BETWEEN 10 AND 20
.
Kemudian baris berikutnya akan menjadi kandidat, ditugaskan dengan ROWNUM = 1
dan gagal, dll., jadi, akhirnya, tidak ada baris yang dikembalikan sama sekali.
Ini harus diatasi dengan meletakkan ROWNUM
's ke dalam subkueri.