Sql-Server

在 SQL Server 2012 中比較兩個大型結果集的最有效方法是什麼

  • November 9, 2018

目前對比較兩個大型結果/行集的最有效方法的建議似乎是使用EXCEPT運算符。隨著行大小的增加(更改 @last 值),下面這個自包含的 SQL 腳本變得非常低效。我試圖在組合表中找到唯一條目,但沒有任何改進。

DECLARE @first AS INT, @step AS INT, @last AS INT; 

-- This script is comparing two record sets using EXCEPT
-- I want to find additions from OLD to NEW
-- As number of rows increase performance gets terrible
-- I don't have to use two tables. I could use one combined table but I want the same result as quickly as possible

-- Compare 100 to 110 rows - 0 seconds
-- Compare 1000 to 1010 rows - 1 seconds
-- Compare 10000 to 10010 rows - 16 seconds
-- Compare 100000 to 100010 rows - ABORT after 8 minutes (tables are populated in 18 seconds)

DECLARE @temptableOLD TABLE ([Result1] int);
SET @step = 1;  SET @first = 1; SET @last = 100000
WHILE(@first <= @last) BEGIN INSERT INTO @temptableOLD VALUES(@first) SET @first += @step END

DECLARE @temptableNEW TABLE ([Result1] int);
SET @step = 1;  SET @first = 1; SET @last = 100010
WHILE(@first <= @last) BEGIN INSERT INTO @temptableNEW VALUES(@first) SET @first += @step END

select * from @temptableNEW
except
select * from @temptableOLD

EXCEPT意味著DISTINCT操作。

NOT EXISTS如果這實際上不是必需的,我會使用。

但是,您遇到的問題很可能是由於與表變數相關的基數估計不佳,您在未索引的表上得到了嵌套循環。

select * from @temptableNEW
except
select * from @temptableOLD
OPTION (RECOMPILE)

將能夠考慮到每個表有 100K 行並給出不同的計劃。

在 SQL Server 2012 中,您只能通過約束向表變數添加索引。如果值是唯一的,您可以使用

DECLARE @temptableOLD TABLE ([Result1] int UNIQUE CLUSTERED);

添加索引。如果在兩個表上都完成,則計劃(在添加重新編譯提示之後)可能會使用合併連接。如果沒有任何索引,我會期望雜湊連接。

引用自:https://dba.stackexchange.com/questions/124630