嵌套 case 语句与多条件 case 语句

Sea*_* K. 1 sql-server optimization

今天与一位同事就优化 case 语句进行了有趣的讨论,以及是否最好将具有重叠标准的 case 语句作为单独的 when 子句保留,或者为每个重叠语句创建一个嵌套的 case 语句。

例如,假设我们有一个包含 2 个整数字段的表,a 列和 b 列。这两个查询中的哪一个对处理器更友好?由于我们只使用嵌套语句评估 a=1 或 a=0 一次,这对处理器来说是否更有效,还是创建嵌套语句会消耗该优化?

case 语句的多个标准:

Select 
case 
    when a=1 and b=0 THEN 'True'
    when a=1 and b=1 then 'Trueish'
    when a=0 and b=0 then 'False'
    when a=0 and b=1 then 'Falseish'
    else null
end AS Result
FROM tableName
Run Code Online (Sandbox Code Playgroud)

嵌套 case 语句:

Select
case
    when a=1 then
        case 
            when b=0 then 'True'
            when b=1 then 'Trueish'
        end
    When a=0 then
        case
            when b=0 then 'False'
            when b=1 then 'Falseish'
        end
    else null
end AS Result
FROM tablename
Run Code Online (Sandbox Code Playgroud)

Jos*_*ell 8

有人可能会过来深入研究这些操作是如何在 CPU 上实际处理的细节,或者在这两个查询之间生成哪些指令不同。 但从实际的角度来看,似乎没有显着差异。

这将加载一个包含 1000 万行的两个位列的表,其中 1 和 0 值的分布有些随意。

CREATE DATABASE [239583];
GO

USE [239583];
GO

SELECT TOP 10000000
    CASE WHEN v.number % 2 = 0 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS a,
    CASE WHEN v.number % 2 = 1 THEN CAST(1 AS bit) ELSE CAST(0 AS bit) END AS b
INTO dbo.TableName
FROM master.dbo.spt_values v
    CROSS JOIN master.dbo.spt_values v2
    CROSS JOIN master.dbo.spt_values v3;
Run Code Online (Sandbox Code Playgroud)

然后我告诉 SSMS 在执行后丢弃结果(查询 -> 查询选项 -> 网格 -> 执行后丢弃结果),因为我没有时间等待 SSMS 崩溃加载 20 毫米的 1 和 0 行。

然后运行这个代码:

SET STATISTICS IO, TIME ON;

Select 
case 
    when a=1 and b=0 THEN 'True'
    when a=1 and b=1 then 'Trueish'
    when a=0 and b=0 then 'False'
    when a=0 and b=1 then 'Falseish'
    else null
end
FROM tableName;

Select 
case
    when a=1 then
        case 
            when b=0 then 'True'
            when b=1 then 'Trueish'
        end
    When a=0 then
        case
            when b=0 then 'False'
            when b=1 then 'Falseish'
        end
    else null
end
FROM tablename;
Run Code Online (Sandbox Code Playgroud)

我典型的运行在我的机器上有这样的 CPU 输出:

Query 1: CPU time = 2141 ms,  elapsed time = 2191 ms.
Query 2: CPU time = 2359 ms,  elapsed time = 2461 ms.
Run Code Online (Sandbox Code Playgroud)

有时它们稍微接近相等,或者第二个查询稍微快一点,但我认为这些只是我的笔记本电脑上 CPU 的常见变体,除了运行这个查询之外,还可以做其他事情。