【发布时间】: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 个语句。