【问题标题】:Oracle 19: Why IN gets converted to Exist in explain plan and any suggestions around itOracle 19:为什么在解释计划中将 IN 转换为 Exist 以及有关它的任何建议
【发布时间】:2022-10-14 01:22:38
【问题描述】:

请看下图:

根据 IN 查询在解释计划中转换为 Exists 。有什么理由吗?这是否意味着 Oracle 会自动将 IN 转换为 Exists?

还有什么降低成本的建议吗?此语句是 SP 的一部分,它接收 ~ 分隔字符串 ('123'),例如 (63278~63282~63285~63288~63291~63296~63299~63302~63305~63308~63311~63314~63319~63322~ 63325~63329~63332~63253~63256~63260~63264~63267~63272~63275~63279~63283~63286~63289~63292~63297~63300~63303~63306~63309~63312~63315~63320~63323~63326~ 63330〜63333〜63269〜63258〜63277〜63294〜63317〜63262〜63270〜63270〜63281〜63295〜63295〜63318〜63318〜63328〜63254 63298~63301~63304~63307~63310~63313~63316~63321~63324~63327~63331~63334)在查询中。执行大约需要 10 到 15 分钟。

我们如何为整个存储过程生成解释计划?我们正在使用 Oracle 19。

先感谢您。

【问题讨论】:

  • 这意味着 Oracle 认为这是最有效的方法,对于此查询,基于统计信息和其他可用数据。这并不意味着它会一直这样做。你的统计数据是最新的吗?什么是生成分隔列表 - 调用者可以传入一组数字吗?
  • 我们从 UI 接收 id。
  • 好的,但是 UI 是否可以将其作为数字集合提供 - 而不是(我猜)将它们连接成一个字符串以传递给您?
  • 如果这是唯一的解决方案,那么是的,我们可以对其进行调整。事实上,我们也可以将它们作为表列发送: TYPE AssocArray_CHAR_ID IS TABLE OF Table.Column%TYPE INDEX BY BINARY_INTEGER;但是,由于这将需要更改前端,因此我正在寻找调整此查询的选项。我尝试了 Exist 但这并没有太大的不同。另外,我不确定统计数据是否是最新的,因为我没有生产服务器访问权限。
  • 由于您是在 PL/SQL 过程中完成这项工作,因此您可以创建(在过程之外)带有 DELETE ON COMMIT 的 GLOBAL TEMPORARY TABLE,在您在该表中插入带有 CONNECT BY 的子选择的结果的过程中,然后您将 SELECT ... CONNECT BY 替换为临时表中的 SELECT。临时表将在过程结束时清空,此方法是会话安全的。而且您可以从索引中受益,并且可能有更好的计划。您还可以将 UPDATE 与 2 个进行比较:将 OR 条件拆分为 2 个语句。

标签: oracle query-optimization


【解决方案1】:

IN 子句检索与给定值集匹配的所有记录。它充当多个OR 条件。 IN 子句扫描从内部查询获取的所有行。 但是,EXISTS 是返回 TrueFalse 的布尔运算符。它与子查询结合使用。如果子查询返回任何行,则返回True,否则返回False。如果IN子句里面的数据很大,那么不推荐使用IN。为了获得高性能,大多数时间使用EXISTSIN。为此,Oracle 和 PostgreSQL 将您的 IN 转换为 EXISTS

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 2020-11-24
    • 1970-01-01
    • 2020-01-08
    相关资源
    最近更新 更多