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

Mengapa Oracle SQL Optimizer mengabaikan predikat indeks untuk tampilan ini?

Oracle tidak menggunakan indeks karena mengasumsikan select column_value from table(x) mengembalikan 8168 baris.

Indeks lebih cepat untuk mengambil sejumlah kecil data. Pada titik tertentu, memindai seluruh tabel lebih cepat daripada menelusuri pohon indeks berulang kali.

Memperkirakan kardinalitas pernyataan SQL biasa cukup sulit. Membuat perkiraan yang akurat untuk kode prosedural hampir tidak mungkin. Tapi saya tidak tahu di mana mereka menemukan 8168. Fungsi tabel biasanya digunakan dengan fungsi pipelined di gudang data, jumlah yang agak besar masuk akal.

Pengambilan sampel dinamis dapat menghasilkan perkiraan yang lebih akurat dan kemungkinan menghasilkan rencana yang akan menggunakan indeks.

Berikut ini contoh perkiraan kardinalitas yang buruk:

create or replace type type_table_of_number as table of number;

explain plan for
select * from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));

Plan hash value: 1748000095

-------------------------------------------------------------------------
| Id  | Operation                             | Name | Rows  | Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |      |  8168 | 00:00:01 |
|   1 |  COLLECTION ITERATOR CONSTRUCTOR FETCH|      |  8168 | 00:00:01 |
-------------------------------------------------------------------------

Berikut cara memperbaikinya:

explain plan for select /*+ dynamic_sampling(2) */ *
                 from table(type_table_of_number(1,2,3,4,5,6,7));
select * from table(dbms_xplan.display(format => '-cost -bytes'));

Plan hash value: 1748000095

-------------------------------------------------------------------------
| Id  | Operation                             | Name | Rows  | Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT                      |      |     7 | 00:00:01 |
|   1 |  COLLECTION ITERATOR CONSTRUCTOR FETCH|      |     7 | 00:00:01 |
-------------------------------------------------------------------------

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. UPDATE pada INSERT duplikat kunci utama di Oracle?

  2. PROSEDUR ORACLe - AUTHID hanya diizinkan di tingkat skema

  3. Tidak termasuk hanya satu nilai MIN pada Oracle SQL

  4. Output Oracle berbeda di SQL Developer dan excel

  5. Bagaimana cara memasukkan lebih dari 1000 nilai ke dalam klausa Oracle IN