Oracle 存储过程 - NOT IN (SUBQUERY) 消耗大量时间
Posted
技术标签:
【中文标题】Oracle 存储过程 - NOT IN (SUBQUERY) 消耗大量时间【英文标题】:Oracle Stored procedure - NOT IN (SUBQUERY) CONSUMES A LOT OF TIME 【发布时间】:2012-06-07 10:20:41 【问题描述】:我有 Oracle 程序,它的工作与以下相同:
create or replace
PROCEDURE My_TEST_PROCEDURE
(
cur out sys_refcursor
)
AS
BEGIN
open cur for
SELECT * FROM MYTABLE1
WHERE MYTABLE1.SOMEROWNAME NOT IN
(SELECT SOMEROWNAME FROM MYTABLE2);
END My_TEST_PROCEDURE;
但这两张表的数据很多,每张大约有300000行。所以需要很长时间才能完成。我能做些什么来减少那段时间。我尝试声明一个 sys_refcursor 并将数据读入这个游标,如下所示:
create or replace
PROCEDURE My_TEST_PROCEDURE
(
cur out sys_refcursor
)
IS
DECLARE EXISTING_ITEMS SYS_REFCURSOR;
BEGIN
OPEN EXISTING_ITEMS FOR
SELECT SOMEROWNAME FROM MYTABLE2;
open cur for
SELECT * FROM MYTABLE1
WHERE MYTABLE1.SOMEROWNAME NOT IN
EXISTING_ITEMS;
END My_TEST_PROCEDURE;
但这一次发生了 ORA-00932 错误。我能做什么?
提前致谢。
【问题讨论】:
查询产生了多少条不匹配的记录? “充足的时间”是多长时间? 【参考方案1】:使用如下的连接查询:
SELECT MYTABLE1.*
FROM MYTABLE1
left join MYTABLE2
ON MYTABLE1.SOMEROWNAME = MYTABLE2.SOMEROWNAME
WHERE MYTABLE2.SOMEROWNAME IS NULL
【讨论】:
会有什么不同? 感谢您的快速回复。但我在 table2 中没有任何空数据。 mytable2 是一个日志文件,我在发送时将 myTable1 中的 ID-s 添加到日志表中,并且我想从 myTable1 中选择未发送的项目。我正在使用日志表,因为我不能在 myTable1 中添加另一列 MYTABLE2.SOMEROWNAME 对于 MyTable1 中没有匹配记录的行将有空数据。【参考方案2】:避免使用*,指定列名。
您为什么使用光标?您正在做的事情可以使用 b.mycolumn 为空的左外连接来实现
最好的问候。
【讨论】:
以上是关于Oracle 存储过程 - NOT IN (SUBQUERY) 消耗大量时间的主要内容,如果未能解决你的问题,请参考以下文章