Apa cara paling efisien untuk membandingkan dua set hasil besar di SQL Server 2012


9

Saran saat ini untuk cara paling efisien untuk membandingkan dua set hasil / baris besar tampaknya menggunakan EXCEPToperator. Script SQL mandiri ini di bawah ini menjadi sangat tidak efisien karena ukuran baris meningkat (ubah nilai-nilai @ terakhir). Saya telah mencoba menemukan entri unik dalam tabel gabungan tetapi tanpa perbaikan.

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

Jawaban:


8

EXCEPTmenyiratkan DISTINCToperasi.

Saya akan menggunakan NOT EXISTSjika ini sebenarnya tidak diperlukan.

Namun masalah yang Anda hadapi kemungkinan besar Anda mendapatkan loop bersarang pada tabel yang tidak terindeks karena perkiraan kardinalitas yang buruk terkait dengan variabel tabel.

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

Akan dapat memperhitungkan bahwa tabel memiliki 100 ribu baris dan memberikan rencana yang berbeda.

Di SQL Server 2012 Anda hanya bisa menambahkan indeks ke tabel variabel melalui batasan. Jika nilainya unik, Anda dapat menggunakannya

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

untuk menambah indeks. Jika dilakukan pada kedua tabel, rencana (setelah petunjuk kompilasi ditambahkan) kemungkinan akan menggunakan gabungan gabung. Tanpa indeks apa pun saya akan mengharapkan hash bergabung.


Martin terima kasih. Ini jawabannya. PILIHAN (RECOMPILE) membantu (100.000 dalam 5 menit), tetapi UNIK yang tergelincir pada kedua tabel membuat peningkatan besar (100.000 dalam 7 detik !!!). Saya hanya membuat tabel ini untuk menunjukkan masalah kehidupan nyata di mana saya tidak memiliki kendali atas pengindeksan tabel pada dua server SQL yang berbeda, tapi saya akan mengelolanya melalui variabel tabel tersebut.
Will Healey

4
#tempTabel @WillHealey memiliki banyak keunggulan dibandingkan variabel tabel (statistik, paralelisme, pengindeksan lebih fleksibel) jadi jika Anda tidak menggunakan ini dalam konteks di mana Anda dibatasi untuk variabel Tabel Anda bisa mencobanya juga.
Martin Smith
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.