【问题标题】:Oracle select execution plan, how to remove FILTERoracle选择执行计划,如何去掉FILTER
【发布时间】:2021-12-28 10:28:12
【问题描述】:

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

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

这个没问题

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'))

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

【问题讨论】:

  • 请显示两个语句的完整执行计划(使用dbms_xplan.display(format => 'TYPICAL +PREDICATE'))。现在还不清楚这里发生了什么。

标签: sql oracle select hints


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 2012-09-02
    • 1970-01-01
    • 2013-09-08
    • 2021-06-16
    • 2013-10-02
    相关资源
    最近更新 更多