优化广泛使用IN子句的Oracle SQL查询

时间:2015-01-12 12:46:16

标签: sql oracle optimization

我维护一个应用程序,我正在尝试优化使用多个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条记录。

如何从优化此查询开始?

2 个答案:

答案 0 :(得分:2)

我真的很喜欢" 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))

关于最大值元素数量Oracle Documentation表示:由于嵌套表没有声明的大小,因此您可以根据需要在构造函数中放置尽可能多的元素

我不知道你有多认真对待这个陈述。

答案 1 :(得分:0)

您应该将所有项目放入一个临时表和显式联接:

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?你应该摆脱那种截然不同的。