SELECT DISTINCT i.name, i.daily_cost
FROM edu_event.items i
WHERE i.purchase_date BETWEEN DATE'2015-01-01' AND DATE'2015-12-31';
对于此查询,选择了以下执行计划:
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5750 | 213K| 206 (1)| 00:00:01 |
| 1 | HASH UNIQUE | | 5750 | 213K| 206 (1)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| ITEMS | 5750 | 213K| 205 (1)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("I"."PURCHASE_DATE">=TO_DATE('2015-01-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "I"."PURCHASE_DATE"<=TO_DATE('2015-12-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
如您所见,原始日期文字被to_date
函数替换。我可以以某种方式禁用它吗?这种格式较大,但是没有提供更多信息,因此我不需要它。 SQL Developer可以通过编程方式将其转换回吗?
答案 0 :(得分:2)
这是Oracle在后台执行的操作,并且不是特殊的SQL Developer视图。格式无法修改:
SQL> explain plan for
2 with rec (d) as (select sysdate from dual)
3 select *
4 from rec
5 where d > date '2018-01-01';
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 4034615273
-----------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
|* 1 | FILTER | | | | |
| 2 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------
1 - filter(SYSDATE@!>TO_DATE(' 2018-01-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss'))
15 rows selected.
您可以使用DBMS_XPLAN.DISPLAY()的 format 参数删除谓词信息,但不能修改其外观
SQL> select * from table(dbms_xplan.display(null, null, '-PREDICATE'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 4034615273
-----------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |
| 1 | FILTER | | | | |
| 2 | FAST DUAL | | 1 | 2 (0)| 00:00:01 |
-----------------------------------------------------------------
9 rows selected.
答案 1 :(得分:1)
如其他答案所述,这就是Oracle重写String.format()
字面量的方式。
例如,在使用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
重要内容-Oracle 了解 日期的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')
。
例如此查询...
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
指向单个分区(#3)
这意味着,Oracle在基于DATE值进行解析时就知道将访问哪个分区(并且可以在优化过程中从中获利)。
因此,简而言之-是的,在日期字符串周围有一个函数调用,但这与列上的函数调用禁止索引访问的情况无法相比。
相反,在使用谓词Pstop
访问上表时,您获得了指向PART_DATE = SYSDATE
分区的执行计划。
KEY
这意味着Oracle知道它将仅访问一个分区,但是不知道哪个分区。