Die Sache ist also, dass Oracle-Zeitstempel und Oracle-Daten zwei verschiedene Datentypen sind. Um einen Zeitstempel mit einem Datum zu vergleichen, muss Oracle eine Konvertierung durchführen - diese INTERNAL_FUNCTION(). Die interessante Designentscheidung besteht darin, dass Oracle die Tabellenspalte und nicht den übergebenen Wert konvertiert, was bedeutet, dass die Abfrage den Index nicht mehr verwendet.
Ich konnte Ihr Szenario in SQL*Plus reproduzieren, also ist es kein Problem mit java.sql.Timestamp
. Das Umwandeln der übergebenen Zeitstempel in Datumsangaben löst das Problem...
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>
Aber ich glaube nicht, dass dir das weiterhilft:Es wäre einfacher, stattdessen einfach Termine zu vergeben.
Interessanterweise hilft es nicht, einen funktionsbasierten Index zu erstellen, der die Datumsspalten in Zeitstempel umwandelt. Die INTERNAL_FUNCTION()
Der Aufruf wird nicht als CAST()
erkannt und der Index wird ignoriert. Versuch, einen Index mit INTERNAL_FUNCTION()
zu erstellen schleudert einen ORA-00904.