我在进行大型查询时遇到问题。
简单来说,[表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)
您还有其他可以想到的方法可以更快或更有效地实现此结果吗?
答案 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函数来查找需要追加的行