请参见下图:
因此,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~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~63281~63295~63318~63328~63254~63257~63261~63265~63268~63273~63276~63280~63284~63287~63290~63293~63298~63301~63304~63307~63310~63313~63316~63321~63324~63327~63331~63334),执行时间约为10 ~ 15分钟。
我们如何为整个存储过程生成解释计划?我们使用的是Oracle 19。
先谢谢你了。
2条答案
按热度按时间2izufjch1#
IN
子句检索与给定值集匹配的所有记录。它充当多个OR
条件。IN
子句扫描从内部查询中提取的所有行。但是,EXISTS
是返回True
或False
的布尔运算符。它与子查询结合使用。如果子查询返回任何行,它返回True
,否则返回False
。如果IN
子句中的结果数据很大,则不建议使用IN
。为了获得高性能,大多数情况下使用EXISTS
而不是IN
。因此,Oracle和PostgreSQL会将您的IN
转换为EXISTS
isr3a4wc2#
由于您是在PL/SQL过程中执行此工作,因此可以创建(在过程之外)一个GLOBAL TEMPORARY TABLE,在过程中您在此表中INSERT子选择的结果,并使用CONNECT BY、然后在临时表中用SELECT替换SELECT... CONNECT BY。临时表将在过程结束时清空,此方法是会话安全的。您可以从索引中获益,并且可能会有更好的计划。您还可以将UPDATE与以下两个计划进行比较:将OR条件拆分为两个语句。