为性能重构UPDATE CASE语句

时间:2016-05-27 13:26:01

标签: sql sql-server sql-update

是否可以在性能方面优化这些查询:

UPDATE PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 2 THEN 9 
                        WHEN ID_STATE = 3 THEN 9 
                        WHEN ID_STATE = 7 THEN 8
                        WHEN ID_STATE = 8 THEN 9
                        ELSE 0
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO
UPDATE PEOPLE  
SET ID_PRESI =  CASE  
                    WHEN ID_PRESI = 3 THEN NULL 
                    WHEN ID_PRESI = 4 THEN NULL 
                    ELSE 0
                END 
WHERE ID_PRESI IN (3,4)
GO
UPDATE STATE_FIC_STATE_PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 2 THEN 9 
                        WHEN ID_STATE = 3 THEN 9 
                        WHEN ID_STATE = 7 THEN 8
                        WHEN ID_STATE = 8 THEN 9
                        ELSE 0
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO
UPDATE STATE_PEOPLE_PRECIS  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 2 THEN 9 
                        WHEN ID_STATE = 3 THEN 9 
                        WHEN ID_STATE = 7 THEN 8
                        WHEN ID_STATE = 8 THEN 9
                        ELSE 0
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO
UPDATE STATE_PEOPLE_PRECIS  
SET ID_PRESI =  CASE  
                    WHEN ID_PRESI = 3 THEN NULL 
                    WHEN ID_PRESI = 4 THEN NULL 
                    ELSE 0
                END 
WHERE ID_PRESI IN (3,4)
GO

5 个答案:

答案 0 :(得分:5)

我会像Rich Benner一样,因为你有很多冗余

UPDATE PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE IN (2,3,8) THEN 9 
                        WHEN ID_STATE = 7 THEN 8
                        ELSE 0
                    END, 
    ID_PRESI =  CASE  
                    WHEN ID_PRESI IN (3,4) THEN NULL 
                    ELSE 0
                END                         
GO

UPDATE STATE_FIC_STATE_PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE IN (2,3,8) THEN 9 
                        WHEN ID_STATE = 7 THEN 8
                        ELSE 0
                    END 
GO

UPDATE STATE_PEOPLE_PRECIS  
SET ID_STATE =  CASE  
                        WHEN ID_STATE IN (2,3,8) THEN 9  
                        WHEN ID_STATE = 7 THEN 8
                        ELSE 0
                    END, 
    ID_PRESI =  CASE  
                    WHEN ID_PRESI IN (3,4) THEN NULL  
                    ELSE 0
                END 

GO

答案 1 :(得分:3)

你在那里有一些冗余代码;

在这一位,你唯一的选择是你的where子句中的4个值,唯一不同的是7(返回8),其他一切返回9;

UPDATE PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 7 THEN 8 
                        ELSE 9
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO

你想要3或4的任何东西都是NULL,你的where子句会这样做。不需要CASE声明;

UPDATE PEOPLE  
SET ID_PRESI =  NULL
WHERE ID_PRESI IN (3,4)
GO

接下来的两个与第一个相同;

UPDATE STATE_FIC_STATE_PEOPLE  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 7 THEN 8 
                        ELSE 9
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO

UPDATE STATE_PEOPLE_PRECIS  
SET ID_STATE =  CASE  
                        WHEN ID_STATE = 7 THEN 8 
                        ELSE 9
                    END 
WHERE ID_STATE IN (2,3,7,8)
GO

我已经从原始答案略微编辑,如果ID_STATE = 7,则案例陈述只需要返回8,否则它是9。

答案 2 :(得分:2)

看起来您有两种更新查询。对于较短的类型,有一个简单的优化,因为实际上不需要CASE(所有与WHERE匹配的条目都设置为NULL)。所以可以改为:

defp log_results(results) do
    {:ok, file} = File.open("data.log", [:append])
    save_results(file, results)
    File.close(file)
end

defp save_results(file, []), do: :ok
defp save_results(file, [data|rest]) do
    IO.binwrite(file, data)
    save_results(file, rest)
end

通过删除CASE,可以对其他更新进行一些优化:

SET ID_PRESI =  NULL
WHERE ID_PRESI IN (3,4)

答案 3 :(得分:2)

只是为了好玩;)

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = (
SELECT REPLACE(
'
    UPDATE {0}
    SET ID_STATE =
            CASE
                WHEN ID_STATE IN (2, 3, 8) THEN 9
                WHEN ID_STATE = 7 THEN 8
                ELSE 0
            END
        ' + CASE WHEN ex = 1 THEN ', ID_PRESI =
            CASE
                WHEN ID_PRESI IN (3, 4) THEN NULL
                ELSE 0
            END
            ' ELSE '' END
            , '{0}', tbl)
    FROM (
        VALUES
            ('PEOPLE', 1),
            ('STATE_FIC_STATE_PEOPLE', 0),
            ('STATE_PEOPLE_PRECIS', 1)
    ) t (tbl, ex)
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')

PRINT @SQL
--EXEC sys.sp_executesql @SQL

答案 4 :(得分:1)

UPDATE
    PEOPLE  
SET
    ID_STATE =  CASE
                    WHEN ID_STATE = 2 THEN 9 
                    WHEN ID_STATE = 3 THEN 9 
                    WHEN ID_STATE = 7 THEN 8
                    WHEN ID_STATE = 8 THEN 9
                    ELSE 0 -- Option 1
                    ELSE ID_STATE -- Option 2
                END,
    ID_PRESI =  CASE  
                    WHEN ID_PRESI = 3 THEN NULL 
                    WHEN ID_PRESI = 4 THEN NULL 
                    ELSE 0 -- Option 1
                    ELSE ID_PRESI -- Option 2
                END;
GO

UPDATE
    STATE_FIC_STATE_PEOPLE  
SET
    ID_STATE =  CASE  
                    WHEN ID_STATE = 2 THEN 9 
                    WHEN ID_STATE = 3 THEN 9 
                    WHEN ID_STATE = 7 THEN 8
                    WHEN ID_STATE = 8 THEN 9
                    ELSE 0 -- Option 1
                    ELSE ID_STATE -- Option 2
                END;
GO

UPDATE
    STATE_PEOPLE_PRECIS  
SET
    ID_STATE =  CASE  
                    WHEN ID_STATE = 2 THEN 9 
                    WHEN ID_STATE = 3 THEN 9 
                    WHEN ID_STATE = 7 THEN 8
                    WHEN ID_STATE = 8 THEN 9
                    ELSE 0 -- Option 1
                    ELSE ID_STATE -- Option 2
                END,
    ID_PRESI =  CASE  
                    WHEN ID_PRESI = 3 THEN NULL 
                    WHEN ID_PRESI = 4 THEN NULL 
                    ELSE 0 -- Option 1
                    ELSE ID_PRESI -- Option 2
                END;
GO