简体   繁体   English

空的LIKE对准备好的语句的性能影响

[英]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.19.29.3

Verify yourself 验证自己

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. 通常在会话期间缓存计划。

Alternative query 替代查询

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM