Saya memiliki masalah besar dengan Pernyataan SQL di Oracle. Saya ingin memilih TOP 10 Records yang dipesan oleh STORAGE_DB yang tidak ada dalam daftar dari pernyataan pilih lainnya.
Ini berfungsi dengan baik untuk semua catatan:
SELECT DISTINCT
APP_ID,
NAME,
STORAGE_GB,
HISTORY_CREATED,
TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') AS HISTORY_DATE
FROM HISTORY WHERE
STORAGE_GB IS NOT NULL AND
APP_ID NOT IN (SELECT APP_ID
FROM HISTORY
WHERE TO_CHAR(HISTORY_DATE, 'DD.MM.YYYY') = '06.02.2009')
Tetapi ketika saya menambahkan
AND ROWNUM <= 10
ORDER BY STORAGE_GB DESC
Saya mendapatkan semacam "acak" Records. Saya pikir karena batasnya terjadi sebelum pesanan.
Apakah seseorang memiliki solusi yang baik? Masalah lainnya: Permintaan ini benar-benar lambat (catatan 10k +)
Jawaban:
Anda harus memasukkan kueri saat ini di subquery seperti di bawah ini:
Oracle menerapkan rownum pada hasilnya setelah dikembalikan.
Anda perlu memfilter hasilnya setelah dikembalikan, sehingga diperlukan subquery. Anda juga dapat menggunakan fungsi RANK () untuk mendapatkan hasil Top-N.
Untuk kinerja coba gunakan
NOT EXISTS
di tempatNOT IN
. Lihat ini untuk lebih lanjut.sumber
FETCH NEXT N ROWS ONLY
jawabannya di bawah ini.Jika Anda menggunakan Oracle 12c, gunakan:
Info lebih lanjut: http://docs.oracle.com/javadb/10.5.3.0/ref/rrefsqljoffsetfetch.html
sumber
Sehubungan dengan kinerja yang buruk ada sejumlah hal yang bisa terjadi, dan itu benar-benar harus menjadi pertanyaan terpisah. Namun, ada satu hal yang jelas bisa menjadi masalah:
Jika HISTORY_DATE benar-benar adalah kolom tanggal dan jika memiliki indeks maka penulisan ulang ini akan berkinerja lebih baik:
Ini karena konversi tipe data menonaktifkan penggunaan indeks B-Tree.
sumber
mencoba
sumber
Anda mendapatkan set yang tampaknya acak karena ROWNUM diterapkan sebelum ORDER BY. Jadi kueri Anda mengambil sepuluh baris pertama dan mengurutkannya.0 Untuk memilih sepuluh gaji teratas, Anda harus menggunakan fungsi analitik dalam subquery, lalu filter itu:
sumber