TIMESTAMP 到 DATE 的转换问题 - 增加查询 运行 时间

Issue with TIMESTAMP to DATE conversion - increasing query run-time

我很想知道这个问题背后的原因是什么 -

例如我有一个查询

SELECT * FROM A WHERE A.DATE = (SELECT B.DATE FROM B)

这里 B.DATE 返回了一行,它的类型是 TIMESTAMP (3) 而 A.DATE 是 DATE 列。

所以 A table 很大,但是对于一个日期它只有 10 万行。上面的 SQL 处理了大约 1000 秒。

我这样做只用了 10 秒 -

SELECT * FROM A WHERE A.DATE = (SELECT CAST(B.DATE AS DATE) FROM B)

有人可以解释一下为什么 CAST 修复了 SQL 运行 时间吗?

Oracle 版本 - 19c

DATETIMESTAMP 之间的类型转换阻止了您在 "DATE" 列上定义的 索引使用 BTW 不要对列名使用保留字 - DATE 必须被引用)

参见下面的示例

EXPLAIN PLAN  SET STATEMENT_ID = 'jara1' into   plan_table  FOR
SELECT * FROM A WHERE A."DATE" =  DATE'2021-01-02';
--    
SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table', 'jara1','ALL'));

 
-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     1 |     8 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| AI   |     1 |     8 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("A"."DATE"=TO_DATE(' 2021-01-02 00:00:00', 'syyyy-mm-dd 
              hh24:mi:ss'))

;

EXPLAIN PLAN  SET STATEMENT_ID = 'jara1' into   plan_table  FOR
SELECT * FROM A WHERE A."DATE" =  TIMESTAMP'2021-01-02 00:00:00.000';
--    
SELECT * FROM table(DBMS_XPLAN.DISPLAY('plan_table', 'jara1','ALL'));

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  1000 |  8000 |    56   (6)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| A    |  1000 |  8000 |    56   (6)| 00:00:01 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter(INTERNAL_FUNCTION("A"."DATE")=TIMESTAMP' 2021-01-02 
              00:00:00.000000000')

所以如果子查询 returns DATE 索引可以使用,但是如果 returns 一个 TIMESTAMP 列值必须转换为 TIMESTAMP 这会阻止 索引访问 (第二个示例)。