Vấn đề là, dấu thời gian của Oracle và ngày tháng của Oracle là hai kiểu dữ liệu khác nhau. Để so sánh dấu thời gian với ngày, Oracle phải chạy một chuyển đổi - INTERNAL_FUNCTION () đó. Quyết định thiết kế thú vị là Oracle chuyển đổi cột bảng chứ không phải giá trị được truyền vào, có nghĩa là truy vấn không còn sử dụng chỉ mục.
Tôi đã có thể tạo lại kịch bản của bạn trong SQL * Plus, vì vậy không có vấn đề gì khi sử dụng java.sql.Timestamp
. Truyền các dấu thời gian đã qua đến ngày tháng không giải quyết được sự cố ...
SQL> explain plan for
2 select * from test1
3 where d1 > cast(to_timestamp('01-MAY-2011 00:00:00.000', 'DD-MON-YYYY Hh24:MI:SS.FF') as date)
4 and d2 > cast(to_timestamp('01-JUN-2011 23:59:59.999', 'DD-MON-YYYY Hh24:MI:SS.FF') as date)
5 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
-----------------------------------------------------------
Plan hash value: 1531258174
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 500 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST1 | 25 | 500 | 3 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_I | 1 | | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
2 - access("D1">CAST(TO_TIMESTAMP('01-MAY-2011 00:00:00.000','DD-MON-YYYY
Hh24:MI:SS.FF') AS date) AND "D2">CAST(TO_TIMESTAMP('01-JUN-2011
23:59:59.999','DD-MON-YYYY Hh24:MI:SS.FF') AS date) AND "D1" IS NOT NULL)
filter("D2">CAST(TO_TIMESTAMP('01-JUN-2011 23:59:59.999','DD-MON-YYYY
Hh24:MI:SS.FF') AS date))
18 rows selected.
SQL>
Nhưng tôi không nghĩ điều đó giúp ích gì cho bạn:thay vào đó, bạn chỉ cần vượt qua ngày tháng sẽ dễ dàng hơn.
Thật thú vị, việc xây dựng chỉ mục dựa trên chức năng truyền các cột ngày thành dấu thời gian không giúp ích được gì. INTERNAL_FUNCTION()
cuộc gọi không được nhận dạng là CAST()
và chỉ mục bị bỏ qua. Đang cố gắng tạo chỉ mục bằng INTERNAL_FUNCTION()
ném ORA-00904.