Как отмечалось в другом ответе, именно так Oracle переписывает литерал DATE
.
Например, при определении многораздельной таблицы с использованием литералов DATE
, как показано ниже.
create table TEST
(id NUMBER,
PART_DATE DATE
)
PARTITION BY RANGE (PART_DATE)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(
PARTITION p1 VALUES LESS THAN (DATE'2018-08-01'),
PARTITION p2 VALUES LESS THAN (DATE'2018-09-01'),
PARTITION p3 VALUES LESS THAN (DATE'2018-10-01')
);
... вы видите HIGH_VALUES
разделов как вызовы функций to_date
:
TO_DATE(' 2018-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
TO_DATE(' 2018-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
TO_DATE(' 2018-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
Что важно - Oracle понимает value
даты .
Например, этот запрос ...
select * from TEST where PART_DATE = DATE'2018-09-15';
... производит следующий план выполнения
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 2 (0)| 00:00:01 | | |
| 1 | PARTITION RANGE SINGLE| | 1 | 22 | 2 (0)| 00:00:01 | 3 | 3 |
|* 2 | TABLE ACCESS FULL | TEST | 1 | 22 | 2 (0)| 00:00:01 | 3 | 3 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("PART_DATE"=TO_DATE(' 2018-09-15 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
Обратите внимание, что предикат FILTER
использует вызов функции to_date
, , но Pstart
и Pstop
указывают на один раздел (# 3)
Это означает, что при синтаксическом анализе Oracle знает на основе значения DATE, к какому разделу будет осуществляться доступ (и может извлечь выгоду из этих знаний при оптимизации).
Короче говоря - да, есть вызов функции вокруг строки даты, но это несопоставимо с ситуацией, когда вызов функции для столбца запрещает доступ к индексу.
Напротив, при доступе к приведенной выше таблице с предикатом PART_DATE = SYSDATE
вы получаете план выполнения, указывающий на KEY
раздел.
|* 2 | TABLE ACCESS FULL | TEST | 1 | 22 | 2 (0)| 00:00:01 | KEY | KEY |
Это означает, что Oracle знает, что получит доступ только к одному разделу, но не знает, какой именно.