优化广泛使用 IN 子句的 Oracle SQL 查询
Posted
技术标签:
【中文标题】优化广泛使用 IN 子句的 Oracle SQL 查询【英文标题】:Optimizing an Oracle SQL query which uses IN clause extensively 【发布时间】:2015-01-12 12:46:15 【问题描述】:我维护了一个应用程序,我在其中尝试优化使用多个 IN 子句的 Oracle SQL 查询。这个查询现在是一个阻塞器,因为它占用了将近 3 分钟的执行时间并且严重影响了应用程序的性能。这个查询是从 Java 代码(JDBC)调用的,看起来像这样:
Select disctinct col1,col2,col3,.. colN from Table1
where 1=1 and not(col1 in (idsetone1,idsetone2,... idsetoneN)) or
(col1 in(idsettwo1,idsettwo2,...idsettwoN))....
(col1 in(idsetN1,idsetN2,...idsetNN))
ID 集是从不同的架构中检索的,因此无法在表 1 的 column1 和 ID 集之间进行 JOIN。随着应用程序的使用,ID 集随着时间的推移而增长,目前它们的记录数超过 10,000 条。
如何开始优化此查询?
【问题讨论】:
为什么要使用多个in
子句?它们都在同一列。将列表合并为一个列表。
如果你使用NOT IN
和OR
需要时间,因此尽量避免像 Gordon Linoff 所说的那样
@GordonLinoff Oracle 在列表中最多接受 1000 个元素。
“不同的架构”到底是什么意思?显然,是可以连接来自不同模式的表:from schema1.table1 join schema2.tabl2...
asktom.oracle.com/pls/asktom/…
【参考方案1】:
我真的很怀疑“ID 集是从不同的架构中检索的,因此无法在表 1 的 column1 和 ID 集之间进行 JOIN。”当然,您可以加入这些表,前提是您有选择权限。
无论如何,让我们假设由于某种原因这是不可能的。一种解决方案是先将所有条目插入到嵌套表中,然后使用这个:
CREATE OR REPLACE TYPE NUMBER_TABLE_TYPE AS TABLE OF NUMBER;
Select disctinct col1,col2,col3,.. colN from Table1
where 1=1
and not (col1 NOT MEMBER OF (NUMBER_TABLE_TYPE(idsetone1,idsetone2,... idsetoneN))
OR
(col1 MEMBER OF NUMBER_TABLE_TYPE(idsettwo1,idsettwo2,...idsettwoN))
关于最大值。 number of elements Oracle Documentation 说:因为嵌套表没有声明的大小,您可以在构造函数中放置 尽可能多的元素根据需要。 em>
我不知道你能把这句话当回事。
【讨论】:
您应该准备带有绑定变量 MEMBER OF :1 的语句,并使用 JDBC 直接构造嵌套表并将其放入其中 - 它将被流式传输到数据库而您没有构建/解析巨大的 SELECT-Strings。它会非常快! 仅供参考 - 你拼错了DISTINCT
,但我看到这是来自 OP【参考方案2】:
您应该将所有项目放入一个临时表并显式连接:
Select your cols
from Table1
left join table_with_items
on table_with_items.id = Table1.col1
where table_with_items.id is null;
另外,distinct
表明您的业务逻辑或应用程序架构存在问题。为什么你有重复的ID?你应该摆脱那个独特的。
【讨论】:
在 Oracle 中使用WHERE NOT EXISTS
而不是外连接不匹配查询可能会更好。以上是关于优化广泛使用 IN 子句的 Oracle SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章