Dalam kueri di bawah ini, kedua rencana eksekusi diperkirakan akan melakukan 1.000 pencarian pada indeks yang unik.
Pencarian didorong oleh pemindaian terurut pada tabel sumber yang sama sehingga tampaknya harus mencari nilai yang sama dalam urutan yang sama.
Kedua loop bersarang miliki <NestedLoops Optimized="false" WithOrderedPrefetch="true">
Adakah yang tahu mengapa tugas ini dihitung biayanya sebesar 0,172434 dalam rencana pertama tetapi 3,01702 di yang kedua?
(Alasan untuk pertanyaan ini adalah bahwa kueri pertama disarankan kepada saya sebagai optimasi karena biaya rencana yang jauh lebih rendah. Sebenarnya itu terlihat bagi saya seolah-olah ia bekerja lebih banyak tetapi saya hanya mencoba menjelaskan perbedaannya .. .)
Mendirikan
CREATE TABLE dbo.Target(KeyCol int PRIMARY KEY, OtherCol char(32) NOT NULL);
CREATE TABLE dbo.Staging(KeyCol int PRIMARY KEY, OtherCol char(32) NOT NULL);
INSERT INTO dbo.Target
SELECT TOP (1000000) ROW_NUMBER() OVER (ORDER BY @@SPID), LEFT(NEWID(),32)
FROM master..spt_values v1,
master..spt_values v2;
INSERT INTO dbo.Staging
SELECT TOP (1000) ROW_NUMBER() OVER (ORDER BY @@SPID), LEFT(NEWID(),32)
FROM master..spt_values v1;
Pertanyaan 1 tautan "Tempel paket"
WITH T
AS (SELECT *
FROM Target AS T
WHERE T.KeyCol IN (SELECT S.KeyCol
FROM Staging AS S))
MERGE T
USING Staging S
ON ( T.KeyCol = S.KeyCol )
WHEN NOT MATCHED THEN
INSERT ( KeyCol, OtherCol )
VALUES(S.KeyCol, S.OtherCol )
WHEN MATCHED AND T.OtherCol > S.OtherCol THEN
UPDATE SET T.OtherCol = S.OtherCol;
Kueri 2 tautan "Tempel paket"
MERGE Target T
USING Staging S
ON ( T.KeyCol = S.KeyCol )
WHEN NOT MATCHED THEN
INSERT ( KeyCol, OtherCol )
VALUES( S.KeyCol, S.OtherCol )
WHEN MATCHED AND T.OtherCol > S.OtherCol THEN
UPDATE SET T.OtherCol = S.OtherCol;
Pertanyaan 1
Pertanyaan 2
Di atas diuji pada SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64)
@ Jo Obbish menunjukkan dalam komentar bahwa repro yang lebih sederhana akan
SELECT *
FROM staging AS S
LEFT OUTER JOIN Target AS T
ON T.KeyCol = S.KeyCol;
vs.
SELECT *
FROM staging AS S
LEFT OUTER JOIN (SELECT * FROM Target) AS T
ON T.KeyCol = S.KeyCol;
Untuk tabel pementasan 1.000 baris kedua di atas masih memiliki bentuk rencana yang sama dengan loop bersarang dan rencana tanpa tabel turunan nampak lebih murah, tetapi untuk tabel pementasan 10.000 baris dan tabel target yang sama seperti di atas perbedaan biaya tidak mengubah rencana bentuk (dengan pemindaian penuh dan gabungan bergabung yang tampaknya relatif lebih menarik daripada upaya berbiaya mahal) menunjukkan perbedaan biaya ini dapat memiliki implikasi selain hanya membuat lebih sulit untuk membandingkan rencana.