我正在寻找最佳解决方案(性能明智)来实现这一目标。
我必须在表格中插入记录,避免重复。
例如,取表A
Insert into A (
Select DISTINCT [FIELDS] from B,C,D..
WHERE (JOIN CONDITIONS ON B,C,D..)
AND
NOT EXISTS
(
SELECT * FROM A ATMP WHERE
ATMP.SOMEKEY = A.SOMEKEY
)
);
我有A.SOMEKEY的索引,只是为了优化NOT EXISTS查询,但我意识到在索引表上插入会受到性能影响。
所以我想在全局临时表中复制表A,在那里我会保留索引。然后,从表A中删除索引并执行查询,但修改了
Insert into A (
Select DISTINCT [FIELDS] from B,C,D..
WHERE (JOIN CONDITIONS ON B,C,D..)
AND
NOT EXISTS
(
SELECT * FROM GLOBAL_TEMPORARY_TABLE_A ATMP WHERE
ATMP.SOMEKEY = A.SOMEKEY
)
);
这将解决“在索引表上插入”,但我必须在每次插入时更新全局临时A。
我有点迷失在这里,
有没有更好的方法来实现这一目标?
提前致谢,
答案 0 :(得分:2)
如果列A.SOMEKEY
被声明为NOT NULL并且如果插入大量数据,则NOT IN子句可能比NOT EXISTS更有效,因为它可以使用HASH ANTI-JOIN。
INSERT INTO A
(SELECT DISTINCT FIELDS
FROM B, C, D ..
WHERE (JOIN CONDITIONS ON B, C, D..)
AND [B].SOMEKEY NOT IN (SELECT SOMEKEY FROM A)
AND [B].SOMEKEY IS NOT NULL;
HASH ANTI-JOINS对于大型数据集非常有效。
在这种情况下,我认为临时表不是一个好主意,因为您将处于以下两种情况之一:
哪种方法效率最高可能取决于数据量。
答案 1 :(得分:0)
如何在表A上设置索引。 使用NOLOGGING
创建表b(与表a相同的结构)Insert /*+APPEND */ into b (
Select DISTINCT [FIELDS] from B,C,D..
WHERE (JOIN CONDITIONS ON B,C,D..)
AND
NOT EXISTS
(
SELECT * FROM A ATMP WHERE
ATMP.SOMEKEY = A.SOMEKEY
)
);
然后将索引放在A和INSERT INTO A SELECT * FROM B
你可以使B成为一个全局临时表,但要确保数据对于会话是持久的,因为丢弃索引将意味地提交。