Saya memiliki kesempatan untuk bermain-main dengan ini, dan komentar saya sebelumnya tentang NOT IN adalah ikan merah dalam kasus ini. Kuncinya adalah keberadaan NULL, atau lebih tepatnya apakah kolom yang diindeks memiliki batasan NOT NULL yang diberlakukan.
Ini akan bergantung pada versi database yang Anda gunakan, karena pengoptimal menjadi lebih pintar dengan setiap rilis. Saya menggunakan 11gR1 dan pengoptimal menggunakan indeks dalam semua kasus kecuali satu:ketika kedua kolom nol dan saya tidak menyertakan NOT IN
klausa:
SQL> desc big_table
Name Null? Type
----------------------------------- ------ -------------------
ID NUMBER
COL1 NUMBER
COL2 VARCHAR2(30 CHAR)
COL3 DATE
COL4 NUMBER
Tanpa klausa NOT IN...
SQL> explain plan for
2 select col4, count(col1) from big_table
3 group by col4
4 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 1753714399
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 31964 | 280K| | 7574 (2)| 00:01:31 |
| 1 | HASH GROUP BY | | 31964 | 280K| 45M| 7574 (2)| 00:01:31 |
| 2 | TABLE ACCESS FULL| BIG_TABLE | 2340K| 20M| | 4284 (1)| 00:00:52 |
----------------------------------------------------------------------------------------
9 rows selected.
SQL>
Ketika saya melakukan dobb NOT IN
klausa kembali, pengoptimal memilih untuk menggunakan index. Aneh.
SQL> explain plan for
2 select col4, count(col1) from big_table
3 where col1 not in (12, 19)
4 group by col4
5 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 343952376
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 31964 | 280K| | 5057 (3)| 00:01:01 |
| 1 | HASH GROUP BY | | 31964 | 280K| 45M| 5057 (3)| 00:01:01 |
|* 2 | INDEX FAST FULL SCAN| BIG_I2 | 2340K| 20M| | 1767 (2)| 00:00:22 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
2 - filter("COL1"<>12 AND "COL1"<>19)
14 rows selected.
SQL>
Sekadar mengulangi, dalam semua kasus lain, selama salah satu kolom yang diindeks dinyatakan tidak nol, indeks digunakan untuk memenuhi kueri. Ini mungkin tidak benar pada versi Oracle sebelumnya, tetapi mungkin menunjukkan jalan ke depan.