Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle menggunakan atau mengabaikan kolom yang diindeks tergantung pada format to_date(literal)

Oke - Saya akan mencobanya, ini sebagian besar adalah potongan dari Informasi yang tersedia:

Mengapa Oracle memilih rencana eksekusi yang berbeda?

Tampaknya dalam kueri kedua Anda dengan Format Tanggal yang tidak biasa, pengoptimal tidak tahu berapa nilai tanggal yang dihasilkan. Anda melihat Predikat Filter:

1 - filter(TO_DATE('20140610 ','yyyymmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'syyyy-mm-dd hh24:mi:ss'))

Yang berarti pengoptimal bahkan tidak yakin bahwa tanggal pertama lebih kecil dari yang kedua! Itu berarti pengoptimal tidak tahu tentang jumlah baris yang dikembalikan dan hanya akan menggunakan rencana umum tanpa memperhitungkan statistik tertentu. Itu akan sama jika Anda memiliki fungsi yang ditentukan pengguna xyt() yang akan mengembalikan tanggal untuk rentang tersebut. Pengoptimal tidak memiliki cara untuk mengetahui nilai tanggal apa yang akan dihasilkan - Ini berarti Anda mendapatkan rencana umum untuk semua tujuan, yang seharusnya cukup baik untuk rentang tanggal apa pun yang ditentukan.

Dalam kasus pertama dan ketiga, pengoptimal tampaknya memahami tanggal secara langsung dan dapat menebak jumlah baris yang berada dalam rentang tanggal dengan menggunakan statistik. Jadi sementara Query kedua adalah ke Optimizer seperti BETWEEN X AND 3 Kueri ini seperti BETWEEN 1 AND 3 Jadi dia mengoptimalkan rencana kueri untuk prediksi jumlah baris yang dikembalikan!

Hal yang aneh tampaknya, bahwa pengoptimal kueri memiliki masalah dengan format tanggal yang aneh, dapat diajukan sebagai bug/permintaan untuk perbaikan...

Tapi Poin penting:

  1. Pemindaian tabel lengkap tidak harus merupakan rencana yang BURUK... Selain menggunakan indeks tidak selalu lebih cepat!
  2. Biaya dalam paket kueri sama sekali tidak terkait langsung dengan waktu atau kinerja eksekusi aktual - ini adalah pengukuran internal untuk membandingkan paket yang berbeda untuk QUERY SAMA (Jadi Anda tidak dapat membandingkan biaya kueri yang berbeda seperti kueri Anda 1 ,2 dan 3)

Pada dasarnya jika Anda mengembalikan sejumlah besar baris dari sebuah tabel, pemindaian tabel penuh tanpa akses indeks dalam banyak kasus akan jauh lebih cepat, terutama ketika beroperasi pada partisi tertentu! - Pemindaian Tabel hanya akan mengakses hak untuk rentang tanggal yang cocok - jadi hanya untuk tanggal yang dimaksud dan mengembalikan semua baris dari partisi ini. Ini jauh lebih cepat daripada menanyakan indeks untuk setiap baris dan kemudian mengekstrak baris dengan akses indeks... Cobalah untuk membuat profil kueri - pemindaian tabel lengkap pada partisi harus 3 kali lebih cepat dengan IO yang jauh lebih sedikit



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. cx_Oracle:Bagaimana saya bisa menerima setiap baris sebagai kamus?

  2. Oracle nomor tidak valid dalam klausa

  3. Oracle tertinggal antara komit dan pilih

  4. Oracle 10g/11g untuk Mac

  5. Oracle LISTAGG() untuk penggunaan kueri