PostgresQL:在 WHERE 中使用 CASE 的性能

PostgresSQL: Performance of using CASE inside WHERE

使用 PostgreSQL,我需要定义一个查询,该查询将根据参数有条件地 SELECT 某些数据。在此语句中,我有一个条件,仅当另一个条件的计算结果为 TRUE.

时才需要计算

为了解决这个问题,我的第一个想法是在 WHERE 中使用 CASE,效果很好。例如,使用具有列 idnamevalue:

的 table test_table
SELECT 
    name
FROM test_table
WHERE
    CASE
        WHEN  > 10 THEN test_table.value > 
        ELSE TRUE
    END
;

但是,其他同行建议改用常规布尔逻辑,因为它会执行得更快。例如:

SELECT 
    name
FROM test_table
WHERE
    (
         <= 10
        OR test_table.value > 
    )
;

在测试了大约 10 万行并使用 EXPLAIN ANALYSE 后,速度差异似乎平均约为 1 毫秒:

问题是:第二种方法真的更快吗?或者是我的测试有缺陷,因此结果不正确?

并不是说不使用 case 总是更快。问题是 case 阻止优化器选择不同的执行路径。它基本上是说条件 要按顺序执行,因为 case 表达式强加顺序。

选项越少,生成的查询计划可能会越慢。

有些情况下执行顺序是优势。当您知道某些条件的评估成本非常高时尤其如此,因此您希望确保首先评估其他条件:

where (case when x = 1 then true
            when <some expensive function> then true
       end)

可能比:

更高效
where (x = 1) or <some expensive function>

(尽管在这个简单的示例中,我希望 Postgres 编译器足够聪明,能够在第二种情况下做正确的事情)。

避免在 where 子句中使用 case 的第二个原因是美观。已经有足够的布尔运算符来生成您需要的几乎任何条件——所以 case 是语法糖,通常不提供额外的营养