【问题标题】:Potsgres Performance: WHERE = Versus WHERE IN (...) for single values [duplicate]Postgres 性能:单个值的 WHERE = Vs WHERE IN (...) [重复]
【发布时间】:2017-11-29 09:21:38
【问题描述】:

我正在开发一个使用 Postgres 作为其后备数据库的应用程序。我正在开发一个在 DB 上执行 SELECT 查询的组件,使用 UI 上的 multi-select 输入控件为查询提供输入值。以前,此输入控件是传统的 select 控件,因此一次只能指定一个选项。这意味着 SQL 查询看起来像这样:

SELECT * FROM items WHERE code = 'value1';

实现多选后,SQL 查询将如下所示:

SELECT * FROM items WHERE code IN ('value1', 'value2', 'value3');

但是,我有一个关于用户何时只在多选中指定单个值的问题。这意味着括号内只指定了一个值:

SELECT * FROM items WHERE code IN ('value1');

我知道这个查询在语义上与使用WHERE ... = ... 的查询相同。我的问题是两者之间是否存在显着的性能差异。如果只指定一个值,我考虑添加应用程序逻辑,选择是否将WHERE ... IN (...) 语句替换为其WHERE ... = ... 对应项?这种优化有必要吗?事实上,如果这两种情况下的性能确实相同,那么当WHERE ... IN (...) 更灵活时,为什么还要使用WHERE ... = ...?我是否过于担心微优化?

谢谢。

【问题讨论】:

  • 复制不是故意的。在询问之前我尝试在 SOF 上查找此问题,但找不到。
  • 这并不是真正的重复,因为上述问题专门针对 Postgres,而指出的已经存在的问题是 MySQL 特有的。不能假设查询的重写规则总是适用于每个 RDBMS。

标签: postgresql where where-in


【解决方案1】:

TLDR:没有区别,性能始终相同,因此IN 显然是您用例的赢家。

可以进行快速测试来验证这一点:

test=# CREATE table test_in (id serial primary key);
CREATE TABLE
test=# explain select * from test_in where id = '1';
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Index Only Scan using test_in_pkey on test_in  (cost=0.15..2.17 rows=1 width=4)
   Index Cond: (id = 1)
(2 rows)

test=# explain select * from test_in where id in ('1');
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Index Only Scan using test_in_pkey on test_in  (cost=0.15..2.17 rows=1 width=4)
   Index Cond: (id = 1)
(2 rows)

注意计划是一样的,索引条件也是一样的,这样可以确保相同的成本不是偶然的。在执行的查询重写阶段,PostgreSQL 检测到一些简单的等价情况并以规范的形式重写它们。

要查看另一个在语义上仍然等效但未重写为完全相同的计划的查询示例,您可以尝试:

test=# explain select * from test_in where id in ('1', '1');
                                   QUERY PLAN
---------------------------------------------------------------------------------
 Index Only Scan using test_in_pkey on test_in  (cost=0.15..3.34 rows=2 width=4)
   Index Cond: (id = ANY ('{1,1}'::integer[]))
(2 rows)

【讨论】:

    【解决方案2】:

    SELECT * FROM items WHERE code = ('value1');(单值)

    处理方式与

    相同

    SELECT * FROM items WHERE code = 'value1';,

    SELECT * FROM items WHERE code IN ('value1');

    所以性能上没有区别。使用explain 进行检查。

    【讨论】:

      猜你喜欢
      • 2016-03-16
      • 2015-10-23
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 2019-09-26
      • 2021-04-17
      • 2016-04-05
      • 2016-01-09
      相关资源
      最近更新 更多