[英]Performance impact of empty LIKE in a prepared statement
I have set a GiST pg_trgm
index on the name
column of the files
table. 我在
files
表的name
列上设置了GiST pg_trgm
索引。
The simplified query of the prepared statement looks like this: 准备好的语句的简化查询如下所示:
SELECT * FROM files WHERE name LIKE $1;
The $1
param will be composed of %
+ user query + %
. $1
参数将由%
+用户查询+ %
。 Since the input might also be an empty string this might result in %%
. 由于输入也可能是空字符串,因此可能会导致
%%
。
Does an "empty" LIKE
( %%
) result in performance degradation? “空”
LIKE
( %%
)是否会导致性能下降? Should I build a new query in that case, or does it not matter? 在这种情况下,我应该建立一个新查询吗?
Postgres 9.2 or later is generally smart enough to realize that the condition Postgres 9.2或更高版本通常足够聪明,可以意识到这种情况
WHERE name LIKE '%%'
is not selective and resorts to a sequential scan ignoring the GiST index - even with prepared statements. 不是选择性的,而是诉诸顺序扫描而忽略GiST索引-即使使用准备好的语句也是如此。 You do pay a small price for the useless condition, though.
但是,您确实为无用的情况付出了很小的代价。
In Postgres 9.1 or earlier I would build a separate query for the special case. 在Postgres 9.1或更早的版本中,我将为特殊情况构建一个单独的查询。
Compare the Notes section for the PREPARE
statement in the manual for the versions 9.1 , 9.2 and 9.3 . 比较的注释部分
PREPARE
手册中陈述的版本9.1 , 9.2和9.3 。
Prepare the statement and run EXPLAIN ANALYZE
to test: 准备语句并运行
EXPLAIN ANALYZE
进行测试:
PREPARE plan1 (text) AS
SELECT * FROM file
WHERE name LIKE $1;
EXPLAIN ANALYZE EXECUTE plan1('%123%');
EXPLAIN ANALYZE EXECUTE plan1('%%');
Plans are generally cached for the duration of the session. 通常在会话期间缓存计划。
Regardless of the version you are running, if you always perform a full text search (wildcards left and right), this query should be faster for a prepared statement: 无论您运行的是哪个版本,如果始终执行全文搜索(左右通配符),则对于准备好的语句,此查询应该更快:
SELECT * FROM files WHERE name LIKE
('%' || $1 || '%');
And pass the pattern without added wildcards ( %
), of course. 当然,传递模式时不添加通配符(
%
)。 This way, Postgres knows to expect a pattern enclosed in wildcards at planning time. 这样,Postgres知道可以在计划时将通配符括起来的模式。
-> SQLfiddle demo. -> SQLfiddle演示。
Note the sequential scan for the empty LIKE and the performance difference between the two plans. 请注意对空LIKE的顺序扫描以及两个计划之间的性能差异。
SQLfiddle varies a lot, depending on load etc. A single run may not be reliable. SQLfiddle的变化很大,具体取决于负载等。单次运行可能不可靠。 Better test in your environment and run each statement a couple of times to saturate cache and eliminate noise.
在您的环境中进行更好的测试,并多次运行每个语句以使缓存饱和并消除噪音。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.