Насколько плохо это переоценка? - PullRequest
2 голосов
/ 13 июля 2011

У меня следующий запрос, мне было интересно, насколько плоха конструкция CASE. Она заставляет DB Engine перезаписать E.EAOpID значением, которое уже содержится в E.EAOpID, когда оно не равно нулю

UPDATE E
SET E.EAOpID =  CASE
                    WHEN E.EAOpID IS NULL THEN @operationID
                    ELSE E.EAOpID
                END,
    E.AverageCapacity = E.AverageCapacity + 1,
    E.Average = E.Average - (E.Average - E.Value) / E.AverageCapacity
FROM
(
    SELECT E.EAOpID, E.AverageCapacity, E.Average, P.Value
    FROM Probes AS P
    INNER JOIN Estimates AS E ON P.EstimateID = E.ID
    WHERE P.EAOpID = @operationID
) AS E;

Может быть, дешевле разделить это ОБНОВЛЕНИЕ на два ОБНОВЛЕНИЯ:

1

UPDATE E
SET E.EAOpID = @operationID
FROM
(
    SELECT E.EAOpID, E.AverageCapacity, E.Average, P.Value
    FROM Probes AS P
    INNER JOIN Estimates AS E ON P.EstimateID = E.ID
    WHERE   P.EAOpID = @operationID
        AND E.EAOpID IS NULL -- Additional statement here
) AS E;

2

UPDATE E
SET E.AverageCapacity = E.AverageCapacity + 1,
    E.Average = E.Average - (E.Average - E.Value) / E.AverageCapacity
FROM
(
    SELECT E.EAOpID, E.AverageCapacity, E.Average, P.Value
    FROM Probes AS P
    INNER JOIN Estimates AS E ON P.EstimateID = E.ID
    WHERE P.EAOpID = @operationID
) AS E;

Ответы [ 3 ]

1 голос
/ 14 июля 2011

Обновление строки, даже если никакие значения не изменились, требует очень мало ресурсов. Вы можете наложить больше нагрузки, просто проверив изменения. Вы могли бы, я полагаю, подумать об оптимизации, подобной этой, когда ваша система очень доработана, и вы едете близко к краю, но в списке она будет низкой.

1 голос
/ 14 июля 2011

Два обновления будут использовать почти вдвое больше ресурсов, так как вы будете читать / обновлять один и тот же набор строк. Лучше иметь все в одном запросе. Я не знаю, как измерить, сколько дополнительной обработки требуется с помощью оператора case, но я знаю, что следующее выполняет тот же объем работы, используя меньше логики кодирования. Измените его с

UPDATE E
 SET E.EAOpID =  CASE
                     WHEN E.EAOpID IS NULL THEN @operationID
                     ELSE E.EAOpID
                 END, 
 (etc)

до

UPDATE E
 SET E.EAOpID = isnull(E.EAOpID, @operationID), 
 (etc)

(Вы можете использовать coalesce вместо isnull, если это вас радует.)

0 голосов
/ 13 июля 2011

Чем больше функций SQL Server вы используете в таблице, тем больше накладных расходов, даже при отсутствии обновления UPDATE.

Операции и дополнительные операции чтения не требуют обслуживания индекса.

Триггеры (триггеры срабатывают), Внешние ключи (целостность по-прежнему проверяется), Ограничения (правила проверяются) и т. Д.

В качестве примера: добавьте ограничение в таблицу, которое не будет работать с некоторыми из существующихзначения, но используя «WITH NOCHECK» для создания.Обновить существующий столбец для себя;обновление не выполнено для ограничения, даже если значение не изменилось.

...