Oracle
 sql >> база данни >  >> RDS >> Oracle

Непренебрежимо малка разлика в плана за изпълнение с Oracle при използване на jdbc Timestamp или Date

И така, работата е, че времевите марки на Oracle и датите на Oracle са два различни типа данни. За да сравни времевия печат с дата, Oracle трябва да изпълни преобразуване - това INTERNAL_FUNCTION(). Интересното дизайнерско решение е, че Oracle преобразува колоната на таблицата, а не предадената стойност, което означава, че заявката вече не използва индекса.

Успях да възпроизведа вашия сценарий в SQL*Plus, така че не е проблем с използването на java.sql.Timestamp . Прехвърлянето на преминатите времеви марки към дати решава проблема...

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>

Но не мисля, че това ви помага с нещо:би било по-лесно просто да минете дати.

Интересното е, че изграждането на базиран на функции индекс, преобразуващ колоните с дата към времеви печати, не помага. INTERNAL_FUNCTION() повикването не се разпознава като CAST() и индексът се игнорира. Опитвам се за изграждане на индекс с помощта на INTERNAL_FUNCTION() хвърля ORA-00904.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Определяне дали данните за полето в Oracle са от тип число

  2. как да замените няколко низа заедно в Oracle

  3. Въведение в архивирането на базата данни на Oracle

  4. Определете Oracle null ==null

  5. Създаване на централен изглед в SQL от SQL таблица