Satu-satunya cara yang saya pikirkan untuk mendapatkan perbedaan seperti itu dalam kecepatan eksekusi adalah dengan (a) memiliki indeks pada field4
, dan (b) memiliki banyak dari blok data kosong; mungkin dari tanda air tinggi yang ditetapkan sangat tinggi oleh beban jalur langsung yang berulang.
Kueri pertama masih akan menggunakan indeks dan berkinerja seperti yang diharapkan. Tetapi karena nilai null tidak diindeks, indeks tidak dapat digunakan untuk memeriksa or field4 is null
kondisi, sehingga akan kembali ke pemindaian tabel penuh.
Itu sendiri seharusnya tidak menjadi masalah di sini, karena pemindaian tabel penuh dari 7000 baris tidak akan memakan waktu lama. Tapi karena adalah begitu lama, sesuatu yang lain sedang terjadi. Pemindaian tabel lengkap harus memeriksa setiap blok data yang dialokasikan ke tabel untuk melihat apakah mereka berisi baris apa pun, dan waktu yang diperlukan menunjukkan bahwa ada lebih banyak blok daripada yang Anda perlukan untuk menyimpan 7000 baris, bahkan dengan penyimpanan CLOB inline.
Cara paling sederhana untuk mendapatkan banyak blok data kosong adalah dengan memiliki banyak data dan kemudian menghapus sebagian besar. Tapi saya yakin Anda mengatakan dalam komentar yang sekarang dihapus pada pertanyaan sebelumnya bahwa kinerja dulu baik-baik saja dan menjadi lebih buruk. Itu bisa terjadi jika Anda melakukan menyisipkan jalur langsung , terutama jika Anda 'menyegarkan' data dengan menghapusnya lalu memasukkan data baru dalam mode jalur langsung. Anda bisa melakukannya dengan sisipan yang memiliki /*+ append */
petunjuk; atau paralel; atau melalui SQL*Loader. Setiap kali Anda melakukannya, tanda air yang tinggi akan bergerak, karena balok-balok tua yang kosong tidak akan digunakan kembali; dan setiap kali kinerja kueri yang memeriksa nol akan sedikit menurun. Setelah banyak iterasi yang akan benar-benar mulai bertambah.
Anda dapat memeriksa kamus data untuk melihat berapa banyak ruang yang dialokasikan untuk tabel Anda (user_segments
dll.), dan bandingkan dengan ukuran data yang menurut Anda sebenarnya Anda miliki. Anda dapat mengatur ulang HWM dengan membangun kembali tabel, misalnya dengan melakukan:
alter table mytable move;
(sebaiknya di jendela pemeliharaan!)
Sebagai demo, saya menjalankan siklus untuk menyisipkan jalur langsung dan menghapus 7000 baris lebih dari seratus kali, dan kemudian menjalankan kedua kueri Anda. Yang pertama membutuhkan waktu 0,06 detik (sebagian besar adalah overhead SQL Devleoper); yang kedua mengambil 1,260. (Saya juga menjalankan Gordon, yang mendapat waktu yang sama, karena masih harus melakukan FTS). Dengan lebih banyak iterasi, perbedaannya akan menjadi lebih mencolok, tetapi saya kehabisan ruang... Saya kemudian melakukan alter table move
dan jalankan ulang kueri kedua Anda, yang kemudian membutuhkan waktu 0,05 detik.