PostgreSQL 性能,使用 ILIKE 仅占两个百分比而不是根本不使用

Posted

技术标签:

【中文标题】PostgreSQL 性能,使用 ILIKE 仅占两个百分比而不是根本不使用【英文标题】:PostgreSQL performance, using ILIKE with just two percentages versus not at all 【发布时间】:2021-01-06 02:28:29 【问题描述】:

我正在使用 ILIKE 根据用户输入搜索行的标题。当用户没有输入任何内容(空字符串)时,所有行都应该返回。

如果您查询带有ILIKE '%%' 的SELECT 语句与完全不使用它,性能会有差异吗?换句话说,是否可以只查询 ILIKE 为空,或者如果没有搜索过滤器文本,我应该在查询中去掉它?

【问题讨论】:

在 oracle 中进行一些测试后(现在没有 postgresql db),即使使用'%%' 它仍然会进行过滤扫描,这确实会导致一些资源,所以对于性能我认为它会最好不要使用过滤文本。 好吧,这就是我的怀疑。谢谢! 查看execution plan 【参考方案1】:

如果查询带有 ILIKE '%%' 的 SELECT 语句与完全不使用它,会有性能差异吗?

两个查询:

select *
from some_table
where some_column ILIKE '%'

select *
from some_table

会返回不同的结果。

第一个等效于 where some_column is not null - 所以它永远不会返回 some_column 为空的行,但第二个会。

所以这不仅关乎性能,还关乎正确性。

就性能而言,它们很可能是相同的——在这两种情况下都使用Seq Scan

【讨论】:

【参考方案2】:

在 PostgreSQL (13.1) 上,这两个查询不等价:

test=# select count(*) from test_ilike where test_string ilike '%%';
 count  
--------
 100000
(1 row)

Time: 87,211 ms
test=# select count(*) from test_ilike where test_string ilike '';
 count 
-------
     0
(1 row)

Time: 85,521 ms

test=# explain analyze select count(*) from test_ilike where test_string ilike '%%';
                                                      QUERY PLAN                                                       
-----------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=2333.97..2333.99 rows=1 width=8) (actual time=86.859..86.860 rows=1 loops=1)
   ->  Seq Scan on test_ilike  (cost=0.00..2084.00 rows=99990 width=0) (actual time=0.022..81.497 rows=100000 loops=1)
         Filter: (test_string ~~* '%%'::text)
 Planning Time: 0.313 ms
 Execution Time: 86.893 ms
(5 rows)
Time: 87,582 ms
test=# explain analyze select count(*) from test_ilike where test_string ilike '';
                                                  QUERY PLAN                                                   
---------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=2084.00..2084.01 rows=1 width=8) (actual time=83.223..83.224 rows=1 loops=1)
   ->  Seq Scan on test_ilike  (cost=0.00..2084.00 rows=1 width=0) (actual time=83.219..83.219 rows=0 loops=1)
         Filter: (test_string ~~* ''::text)
         Rows Removed by Filter: 100000
 Planning Time: 0.104 ms
 Execution Time: 83.257 ms
(6 rows)

Time: 83,728 ms

【讨论】:

我认为问题是 ... ILIKE '%' 与根本没有 ILIKE 条件。

以上是关于PostgreSQL 性能,使用 ILIKE 仅占两个百分比而不是根本不使用的主要内容,如果未能解决你的问题,请参考以下文章

postgresql数据库中~和like和ilike的区别

在 PostgreSQL 中查询 iLike 列表

PostgreSQL hstore:使用索引提高LIKE性能?

LOWER LIKE vs iLIKE

sql SQL - LIKE / ILIKE + IN在Postgresql中

Postgresql 包含在 where 子句中