2017-02-02 16 views
-1

Не удается понять, почему мой запрос занимает так много времени, ища советы по оптимизации.Запрос на выполнение плана выполнения SQL Server

update Laserbeak_Main.dbo.ACCOUNT_MPN set 
    DateUpgrade = ord.ConnectedDate 
        FROM [ORDER] ord 
        WHERE ord.AccountNumber = Laserbeak_Main.dbo.ACCOUNT_MPN.AccountNumber 
        AND ord.ordertypeID = '2' 
        AND ord.ConnectedDate IS NOT NULL 
        AND DateUpgrade <> ord.ConnectedDate 

enter image description here

Execution plan as requested on brentozar.com

UPDATE: После предложений новый запрос выглядит следующим образом &, кажется, работает гораздо быстрее. Однако, если вы запустите запрос, он задает строки, как ожидалось, затем запустите снова, он обновит то же количество строк. Преобразование в select подтверждает, что одни и те же строки обновляются каждый раз. Предложение <> должно остановить это, но это не так. Я полагал, что это связано с сортировкой, но не удалось подтвердить, возможно ли иметь разные сопоставления на уровне таблицы в одной базе данных.

;WITH cteOrderInfo AS (
SELECT DISTINCT ord.AccountNumber, ord.ConnectedDate 
FROM [ORDER] ord 
WHERE ord.ordertypeID = '2' 
AND ord.ConnectedDate IS NOT NULL 
) 
UPDATE Laserbeak_Main.dbo.ACCOUNT_MPN 
SET Laserbeak_Main.dbo.ACCOUNT_MPN.DateUpgrade = cteOrderInfo.ConnectedDate 
FROM cteOrderInfo 
INNER JOIN Laserbeak_Main.dbo.ACCOUNT_MPN acc 
ON cteOrderInfo.AccountNumber = acc.AccountNumber 
WHERE cteOrderInfo.ConnectedDate <> acc.DateUpgrade 

SELECT, чтобы подтвердить:

;WITH cteOrderInfo AS (
SELECT DISTINCT ord.AccountNumber, ord.ConnectedDate 
FROM [ORDER] ord 
WHERE ord.ordertypeID = '2' 
AND ord.ConnectedDate IS NOT NULL 
) 
SELECT cteOrderInfo.ConnectedDate, acc.DateUpgrade 
FROM cteOrderInfo 
INNER JOIN Laserbeak_Main.dbo.ACCOUNT_MPN acc 
ON cteOrderInfo.AccountNumber = acc.AccountNumber 
WHERE cteOrderInfo.ConnectedDate <> acc.DateUpgrade 

Выбирите Результаты Пример:

enter image description here

+1

Не относится к оптимизации запросов, но ваш запрос может быть легче читать, если вы реструктурировать его немного: 'UPDATE согласно SET DateUpgrade = ord.ConnectedDate ОТ dbo.ACCOUNT_MPN согласно INNER JOIN dbo.ORDER Ord ON acc.AccountNumber = dbo.AccountNumber И ord.orderTypeID = 2' – Serge

+1

Столбец 'AccountNumber' в таблице' ORDER' не уникален, не так ли? Если это так, если только предложение 'WHERE' не ограничивает набор данных, запрос будет обновлять каждую строку в таблице ACCOUNT_MPN' несколько раз. Чтобы избежать этого, вместо 'FROM ORDER' вы можете: a). используйте подзапрос с ключевым словом 'DISTINCT'; б). использовать подзапрос с предложением GROUP BY; или c). добавьте дополнительные условия в существующее предложение WHERE. – Serge

+1

Можете вставить план выполнения здесь и поделиться ссылкой: https: //www.brentozar.com/pastetheplan/ – TheGameiswar

ответ

0

Как предположил Сергей, у нас не было уникальных строк.

решения мы прибыли:

;WITH cteSourceStuff AS (
     SELECT AccountNumber, MpnUpgrade, MAX(DateConnected) maxConnDate 
     FROM ORDER_DETAIL, [ORDER] 
     WHERE ORDER_DETAIL.OrderID = [ORDER].OrderID 
     AND LEN(MpnUpgrade) > 10 
     AND OrderTypeID = 2 
     GROUP BY AccountNumber, MpnUpgrade 
    ) 
     UPDATE Laserbeak_Main.dbo.ACCOUNT_MPN set 
       DateUpgrade = cteSourceStuff.maxConnDate 
       FROM cteSourceStuff 
       WHERE cteSourceStuff.MpnUpgrade = ACCOUNT_MPN.Mpn 
       AND cteSourceStuff.AccountNumber = ACCOUNT_MPN.AccountNumber 
       AND DateUpgrade <> cteSourceStuff.maxConnDate 

Это работает, потому что дубликаты первоначально удалены, то мы обновляем только те строки, которые мы на самом деле таргетинг. Причина, по которой у нас были проблемы, заключалась в том, что SQL обновлял найденную первую строку, а затем, когда мы повторно запускали или запускали выбор, это были строки возврата, сопоставленные с ключом, но которые ранее не были обновлены.