1

我在表格的列pg_trgm上设置了一个 GiST 索引。namefiles

准备好的语句的简化查询如下所示:

SELECT * FROM files WHERE name LIKE $1;

$1参数将由%+ 用户查询 +%组成。由于输入也可能是一个空字符串,这可能会导致%%.

“空” LIKE( %%) 是否会导致性能下降?在这种情况下我应该建立一个新的查询,还是没关系?

4

1 回答 1

2

Postgres 9.2 或更高版本通常足够聪明,可以意识到条件

WHERE name LIKE '%%'

不是选择性的,而是采用忽略 GiST 索引的顺序扫描 - 即使使用准备好的语句。但是,您确实为无用的条件付出了很小的代价。

在 Postgres 9.1 或更早版本中,我将为特殊情况构建一个单独的查询。

比较版本9.1、9.29.3的手册中语句的注释部分PREPARE

验证自己

准备语句并运行EXPLAIN ANALYZE测试:

PREPARE plan1 (text) AS
SELECT  * FROM file
WHERE   name LIKE $1;

EXPLAIN ANALYZE EXECUTE plan1('%123%');

EXPLAIN ANALYZE EXECUTE plan1('%%');

计划通常在会话期间被缓存。

替代查询

无论您运行的是什么版本,如果您始终执行全文搜索(通配符左右),则对于准备好的语句,此查询应该更快:

SELECT * FROM files WHERE name LIKE ('%' || $1 || '%');

%当然,在不添加通配符 ( ) 的情况下传递模式。通过这种方式,Postgres 知道在计划时期望一个包含在通配符中的模式。

-> SQLfiddle 演示。
注意空 LIKE 的顺序扫描以及两个计划之间的性能差异。
SQLfiddle 变化很大,具体取决于负载等。单次运行可能不可靠。在您的环境中进行更好的测试并运行每个语句几次以使缓存饱和并消除噪音。

于 2013-09-25T17:07:12.140 回答