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

Oracle - Penggunaan indeks dengan parameter opsional

NVL trik seharusnya berfungsi dan memungkinkan akses indeks. Faktanya, NVL umumnya cara terbaik untuk melakukan ini, dan biasanya bekerja lebih baik daripada kondisi lain yang melibatkan CASE atau OR . Saya telah menggunakan NVL trik berkali-kali dan kasus uji sederhana di bawah ini menunjukkan bahwa ia dapat menggunakan indeks.

Skema

create table xx_people(id_number number, a number, b number);

insert into xx_people
select level, level, level from dual connect by level <= 100000;

commit;

begin
    dbms_stats.gather_table_stats(user, 'xx_people');
end;
/

create index xx_people_idx1 on xx_people(id_number, -1);

Buat Rencana Eksekusi

explain plan for
select *
from xx_people
where id_number = nvl(:p_id_number, id_number);

select * from table(dbms_xplan.display);

Rencana Eksekusi

Plan hash value: 3301250992

----------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                 |   100K|  3808K|   106   (1)| 00:00:01 |
|   1 |  VIEW                                  | VW_ORE_67373E14 |   100K|  3808K|   106   (1)| 00:00:01 |
|   2 |   UNION-ALL                            |                 |       |       |            |          |
|*  3 |    FILTER                              |                 |       |       |            |          |
|   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| XX_PEOPLE       |     1 |    15 |     3   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN                  | XX_PEOPLE_IDX1  |     1 |       |     2   (0)| 00:00:01 |
|*  6 |    FILTER                              |                 |       |       |            |          |
|*  7 |     TABLE ACCESS FULL                  | XX_PEOPLE       |   100K|  1464K|   103   (1)| 00:00:01 |
----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(:P_ID_NUMBER IS NOT NULL)
   5 - access("ID_NUMBER"=:P_ID_NUMBER)
   6 - filter(:P_ID_NUMBER IS NULL)
   7 - filter("ID_NUMBER" IS NOT NULL)

Rencana itu agak membingungkan pada awalnya. Tapi itu punya yang terbaik dari kedua dunia; operasi filter memungkinkan Oracle untuk memutuskan pada saat run time untuk menggunakan pemindaian tabel lengkap ketika variabel bind adalah nol (dan semua baris dikembalikan), dan indeks ketika variabel bind tidak nol (dan hanya beberapa baris yang dikembalikan).

Ini semua berarti bahwa mungkin ada sesuatu yang aneh terjadi dalam kasus spesifik Anda. Anda mungkin perlu memposting kasus uji yang sepenuhnya dapat direproduksi agar kami mengetahui mengapa indeks tidak digunakan.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. mengaudit 50 kolom menggunakan pemicu oracle

  2. Ubah string yang dibatasi menjadi baris di Oracle

  3. Metaprogramming Oracle sql pilih pernyataan

  4. Validasi tanggal di Oracle tanpa menggunakan fungsi

  5. Punya Tabel Oracle Dinamakan sebagai Kata Cadangan, Masalah apa yang mungkin muncul?