Tôi đã có cơ hội để chơi với điều này, và các nhận xét trước đây của tôi về KHÔNG VÀO là một con cá trích đỏ trong trường hợp này. Điều quan trọng là sự hiện diện của NULL, hay đúng hơn là liệu các cột được lập chỉ mục có thực thi các ràng buộc KHÔNG NULL hay không.
Điều này sẽ phụ thuộc vào phiên bản cơ sở dữ liệu bạn đang sử dụng, vì trình tối ưu hóa trở nên thông minh hơn với mỗi bản phát hành. Tôi đang sử dụng 11gR1 và trình tối ưu hóa đã sử dụng chỉ mục trong mọi trường hợp ngoại trừ một trường hợp:khi cả hai cột đều rỗng và tôi không bao gồm NOT IN
mệnh đề:
SQL> desc big_table
Name Null? Type
----------------------------------- ------ -------------------
ID NUMBER
COL1 NUMBER
COL2 VARCHAR2(30 CHAR)
COL3 DATE
COL4 NUMBER
Nếu không có mệnh đề 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>
Khi tôi đánh dấu NOT IN
trở lại mệnh đề, trình tối ưu hóa đã chọn sử dụng chỉ mục. Kỳ lạ.
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>
Xin nhắc lại, trong tất cả các trường hợp khác, miễn là một trong các cột được lập chỉ mục được khai báo không phải là nill, chỉ mục được sử dụng để đáp ứng truy vấn. Điều này có thể không đúng trên các phiên bản trước của Oracle, nhưng nó có thể chỉ ra con đường phía trước.