У запитах нижче, як обидва плани виконання, за оцінками, виконують 1000 запитів за унікальним індексом.
Шукання керуються впорядкованим скануванням в одній таблиці джерел, так що, здавалося б, слід шукати однакові значення в тому ж порядку.
Обидві вкладені петлі мають <NestedLoops Optimized="false" WithOrderedPrefetch="true">
Хтось знає, чому в першому плані це завдання коштує 0,172434, а в другому 3,01702?
(Причина для цього полягає в тому, що перший запит був запропонований мені як оптимізація через очевидну значно меншу вартість плану. Насправді мені здається, що це робить більше роботи, але я просто намагаюся пояснити невідповідність.) .)
Налаштування
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;
Запит 1 Посилання "Вставити план"
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;
Запит 2 Посилання "Вставити план"
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;
Запит 1
Запит 2
Вищезазначене було протестовано на SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64)
@Joe Obbish в коментарях вказує, що простішим докором було б
SELECT *
FROM staging AS S
LEFT OUTER JOIN Target AS T
ON T.KeyCol = S.KeyCol;
проти
SELECT *
FROM staging AS S
LEFT OUTER JOIN (SELECT * FROM Target) AS T
ON T.KeyCol = S.KeyCol;
Для таблиці таблиці рядків на 1000 рядків обидва вищезазначені все ще мають однакову форму плану з вкладеними петлями та планом, без того, щоб похідна таблиця виявилася дешевшою, але для таблиці 10000 рядків послідовності та тієї ж цільової таблиці, що вище, ніж різниця у витратах, змінює план форма (з повним скануванням та об'єднанням об'єднань, здається порівняно привабливішою, ніж прагне дорого коштувати), що показує, що ця невідповідність витрат може мати інші наслідки, ніж просто ускладнювати порівняння планів.