Обновление табличной переменной с выходом объединенной табличной функции против значений переменных? - PullRequest
0 голосов
/ 14 марта 2012

Учитывая следующую табличную переменную, которая содержит, скажем, несколько записей по 10 КБ:

DECLARE @SomeTable TABLE
(
    ID int IDENTITY (1, 1) PRIMARY KEY NOT NULL,
    Name varchar(100),
    CustomerMailingAddress1 varchar(100),
    CustomerMailingAddress2 varchar(100),
    CustomerMailingAddress3 varchar(100),
    CustomerMailingAddress4 varchar(100),
    ContactInfo1 nvarchar(256),
    ContactInfo2 nvarchar(256)
)

В настоящее время табличная переменная обновляется в sproc следующим образом:

UPDATE st
SET
    ContactInfo1 = ci.ContactInfo1,
    ContactInfo2 = ci.ContactInfo2
FROM @SomeTable st, dbo.ContactInfoFunc() AS ci

Табличная функция dbo.ContactInfoFunc() просто извлекает запись MAX в соответствии с первичным ключом таблицы с одной записью (это контактная информация компании, которая редко, если вообще изменится).

По производительности вышеупомянутое обновление дороже? Другими словами, будет ли какое-либо преимущество переписывать обновление, чтобы исключить объединение с выводом табличной функции следующим образом:

DECLARE @ContactInfo1 nvarchar(256), @ContactInfo2 nvarchar(256)

SELECT @ContactInfo1 = ContactInfo1, @ContactInfo2 = ContactInfo2
FROM dbo.ContactInfoFunc()

UPDATE st
SET
    ContactInfo1 = @ContactInfo1,
    ContactInfo2 = @ContactInfo2
FROM @SomeTable st

Или это жеребьевка? Будет ли оптимизатор запросов достаточно умен, чтобы кэшировать выходные данные табличной функции, или он будет крутиться, выполняя функцию для каждой обновляемой строки?

1 Ответ

1 голос
/ 14 марта 2012

Не уверен, что еще вы делаете с табличной переменной, но зачем вам вообще нужно ее обновлять?Давайте предположим, что вы в итоге делаете SELECT из этого в конце.Таким образом, ваш код может быть легко:

DECLARE @ContactInfo1 nvarchar(256), @ContactInfo2 nvarchar(256)

SELECT @ContactInfo1 = ContactInfo1, @ContactInfo2 = ContactInfo2
FROM dbo.ContactInfoFunc();

...

SELECT 
    ID,
    Name,
    CustomerMailingAddress1,
    CustomerMailingAddress2,
    CustomerMailingAddress3,
    CustomerMailingAddress4,
    ContactInfo1 = @ContactInfo1, -- these don't need to be a fixture in the table to
    ContactInfo2 = @ContactInfo2  -- be involved in the resultset or other activity...
FROM @SomeTable;

Теперь мой ответ был бы другим, если бы функция действительно принимала параметры, а вывод зависел от этих параметров.Тогда может иметь смысл выполнить CROSS APPLY, возможно ... но опять-таки не выполнять UPDATE, просто как функцию окончательного SELECT ...

...