在DB2 / SQL中用另一个大表过滤大表的最佳方法?

时间:2018-12-26 23:18:42

标签: sql join db2

我在进行大型查询时遇到问题。

简单来说,[表A]包含约600万个ID,[表B]具有约400万个ID。我需要在[表B]中附加[表B]中尚未存在的[表A]中的ID(两个表中都重复了许多ID,因为它们具有其他具有不同值的列)。 [表A]和[表B]都是CTE。

我已经尝试了所有方法,从A.ID为空的LEFT OUTER JOIN,到NOT IN一直到WHERE NOT EXISTS,但它们都需要花很多时间才能运行:

SELECT
ID
OTHER COLUMNS
FROM A LEFT OUTER JOIN B ON A.ID = B.ID
WHERE B.ID IS NULL

SELECT
ID
OTHER COLUMNS
FROM A
WHERE A.ID NOT IN (SELECT ID FROM B)

您还有其他可以想到的方法可以更快或更有效地实现此结果吗?

3 个答案:

答案 0 :(得分:0)

根据您的评论“感谢您的答复。您在id列上使用索引是什么意思?”,您需要确保bot表在ID上具有索引。 假设在这两种情况下,ID都是唯一的并且是主键,则应运行:

ALTER TABLE A ADD PRIMARY KEY (ID)
ALTER TABLE B ADD PRIMARY KEY (ID)

然后它应该可以正常运行,我建议您使用如下的NOT EXISTS子句:

SELECT
ID
OTHER COLUMNS
FROM A
WHERE NOT EXISTS (SELECT ID FROM B WHERE A.ID = B.ID)

如果仍然很慢,则按如下所示分成较小的组:

WHILE 1 = 1
BEGIN
BEGIN TRANSACTION;
SELECT TOP 100000 
ID
OTHER COLUMNS
FROM A
WHERE NOT EXISTS (SELECT ID FROM B WHERE A.ID = B.ID);
IF @@ROWCOUNT = 0 
BEGIN
     COMMIT
     BREAK
END
COMMIT;
END;

这将对您在“ SELECT TOP 100000”行上选择的行数进行单独的事务。

答案 1 :(得分:0)

要从a中的b中选择记录。通常,异常连接会比not in子句快一些,因为sql处理器将充分利用索引。

select blah from table a exception join table b on a.id = b.id

答案 2 :(得分:-1)

您是否尝试过将GROUP BY用于您的列?在T-SQL中,GROUP BY使对CTE表的查询运行速度提高了约30倍,与临时表相当。您还可以探索使用EXCEPT函数来查找需要追加的行