sql >> Databasteknik >  >> RDS >> Oracle

Icke försumbar skillnad i exekveringsplan med Oracle vid användning av jdbc Timestamp eller Date

Så grejen är att Oracle-tidsstämplar och Oracle-datum är två olika datatyper. För att jämföra en tidsstämpel med ett datum måste Oracle köra en konvertering - den INTERNAL_FUNCTION(). Det intressanta designbeslutet är att Oracle konverterar tabellkolumnen snarare än det godkända värdet, vilket innebär att frågan inte längre använder indexet.

Jag har kunnat återskapa ditt scenario i SQL*Plus, så det är inga problem med att använda java.sql.Timestamp . Att casta de passerade tidsstämplarna till datum löser problemet...

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>

Men jag tror inte att det hjälper dig något:det skulle vara lättare att bara passera dejter istället.

Intressant nog hjälper det inte att bygga ett funktionsbaserat index som gjuter datumkolumnerna till tidsstämplar. INTERNAL_FUNCTION() anropet känns inte igen som en CAST() och indexet ignoreras. Försöker bygga ett index med INTERNAL_FUNCTION() kastar en ORA-00904.



  1. Hur FORMAT()-funktionen fungerar i SQL Server (T-SQL)

  2. Databas endast backuper i WHM

  3. Undvik HA/DR Solution Self-Delusion

  4. MySQL Ordna efter ett nummer, null sist