【问题标题】:PostgresSQL: Performance of using CASE inside WHEREPostgresQL:在 WHERE 中使用 CASE 的性能
【发布时间】:2020-08-19 19:43:22
【问题描述】:

使用 PostgreSQL,我需要定义一个查询,该查询会根据参数有条件地SELECT 一些数据。在此语句中,我有一个条件,仅当另一个条件评估为 TRUE 时才需要评估。

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

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

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

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

在对大约 100k 行进行测试并使用EXPLAIN ANALYSE 后,速度差异似乎平均为大约 1ms 差异:

  • 使用CASE:~19.5ms 执行时间
  • 使用常规布尔值:~18.5ms 执行时间

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

【问题讨论】:

  • 只有 1 毫秒的差异,我怀疑文件是否存在真正的差异。这可能只是由于其他原因造成的随机差异。变化。您多久运行一次查询?
  • 嗨@a_horse_with_no_name。每种方法 20 次。然后计算这些时间的平均值。
  • 我仍然认为 1ms 是不够的。能否请edit您的问题并为每个查询添加explain (analyze, buffers)*的输出(请格式化文本,不要屏幕截图)

标签: sql postgresql query-performance


【解决方案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 是语法糖,通常不提供额外的营养

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2023-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    相关资源
    最近更新 更多