Potsgres性能:WHERE =与单个值的WHERE IN(...)对比

时间:2017-06-26 13:51:27

标签: postgresql where where-in

我正在开发一个使用 Postgres 作为其后备数据库的应用程序。我正在研究一个在数据库上执行SELECT查询的组件,使用UI上的多选输入控件来提供查询的输入值。以前,此输入控件是传统的选择控件,因此一次只能指定一个选项。这意味着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 ... = ...更灵活时,为什么还要使用WHERE ... IN (...)呢?我对微优化过于担心吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

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

的处理方式与

相同

SELECT * FROM items WHERE code = 'value1';

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

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

答案 1 :(得分:2)

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)