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

Oracle 11 Index hanya untuk sebagian data

Biarkan saya memastikan saya memahami pertanyaan dengan benar:

  • Anda ingin mempercepat SELECT .. WHERE C_D IS NULL tetapi Anda tidak ingin mempercepat kueri apa pun yang menelusuri C_D non-NULL.
  • Anda juga ingin memastikan tidak ada nilai non-NULL yang "tidak perlu" dalam indeks, untuk menghemat ruang.

Jika pemahaman itu benar, maka yang Anda butuhkan adalah fungsional indeks. Yaitu. indeks pada fungsi pada bidang, bukan bidang itu sendiri...

CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS

...yang kemudian akan Anda kueri sebagai...

SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...yang setara dengan...

SELECT * FROM T WHERE C_D IS NULL

...tetapi lebih cepat karena menggunakan indeks:

Ini menghemat ruang karena indeks kolom tunggal tidak menyimpan NULL. Juga, gunakan COMPRESS karena indeks hanya akan berisi satu kunci sehingga tidak perlu membuang ruang untuk mengulang kunci yang sama berulang kali dalam struktur indeks.

CATATAN:Di bawah Oracle 11, Anda juga dapat membuat kolom virtual berbasis fungsi (berdasarkan CASE ekspresi di atas), lalu indeks dan kueri pada kolom itu secara langsung, untuk menyimpan beberapa pengetikan berulang.

--- EDIT ---

Jika Anda juga tertarik untuk menanyakan tentang C_I bersama dengan C_D IS NULL , Anda bisa...

CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)

...dan menanyakannya dengan (misalnya)...

SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...yang setara dengan...

SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL

...tapi lebih cepat, karena menggunakan indeks T_IE2 .

Ini sebenarnya satu-satunya indeks yang Anda butuhkan di meja Anda (itu "mencakup" kunci utama, jadi Anda tidak lagi memerlukan indeks terpisah hanya di C_I). Yang juga berarti ROWID yang sama tidak pernah disimpan di lebih dari satu indeks, yang menghemat ruang.

CATATAN:COMPRESS tidak lagi masuk akal untuk indeks T_IE2 .

--- EDIT 2 ---

Jika Anda lebih mementingkan kesederhanaan daripada ruang, Anda bisa membuat indeks komposit di {C_I, C_D}. Oracle menyimpan nilai NULL dalam indeks komposit selama setidaknya ada satu nilai non-NULL dalam tupel yang sama:

CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)

Ini menggunakan indeks:

SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL

Seperti pada EDIT sebelumnya, ini adalah satu-satunya indeks yang Anda butuhkan di meja Anda.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pemicu Modifikasi Sesi?

  2. Klarifikasi pada rownum

  3. Cara men-debug Prosedur Tersimpan Java di Oracle

  4. Mengubah format tanggal

  5. Cara Mendefinisikan Kunci Utama Peningkatan Otomatis di Oracle