1

我有远程连接到非 oracle 数据库。

我尝试执行两个 sql 的 . 远程数据库上的列日为 char。

这工作正常

select * from tab
where day='2021-11-11'

执行计划

PLAN_TABLE_OUTPUT

Plan hash value: 1788691278
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Inst   |IN-OUT|
|   0 | SELECT STATEMENT |             |    20 | 44760 |   200   (0)| 00:00:01 |        |      |
|   1 |  REMOTE          | EV_LOGS     |    20 | 44760 |   200   (0)| 00:00:01 | RS_HD~ | R->S |

这永远不会结束

select * from tab
where day=to_char(sysdate-5,'yyyy-mm-dd')
PLAN_TABLE_OUTPUT

Plan hash value: 2703195431
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     | Inst   |IN-OUT|
|   0 | SELECT STATEMENT |             |    20 | 44760 |   200   (0)| 00:00:01 |        |      |
|*  1 |  FILTER          |             |    20 | 44760 |   200   (0)| 00:00:01 |        |      |
|   2 |   REMOTE         | EV_LOGS     |       |       |            |          | RS_HD~ | R->S |

Predicate Information (identified by operation id):
   1 - filter("day"=TO_CHAR(SYSDATE@!-20,'yyyy-mm-dd'))

我尝试了不同的提示,但其中任何一个都没有帮助。我想我可以重写它以立即执行,但是如何避免呢?

4

1 回答 1

1

在第一个计划中,REMOTE 意味着我们可以通过线路将谓词发送到远程数据库。因此,可以远程应用过滤,并且只返回结果数据。

在第二个示例中,我们知道“SYSDATE-5”实际上是一个常量,但数据库没有 - 它会将其视为一个表达式,并且将表达式发送到远程数据库通常是有风险的,因为表达式可能评估为不同的结果取决于您使用的数据库。远程数据库可能在不同的时区/语言环境等中运行,因此跨行发送它是不安全的。

如果您需要这样做,也许可以在本地评估该值,然后将其作为绑定变量通过链接静态发送。

于 2021-11-19T02:08:12.427 回答