PostgreSQL trigram索引字符中的行为< 3

时间:2017-06-27 07:15:38

标签: sql postgresql

在我的PostgreSQL数据库中,我有import java_cup.runtime.*; /* Terminals (tokens returned by the scanner). */ terminal FCONST; terminal IDENTIFIER; terminal STRING_DEFINITION; terminal ASSIGN; terminal OPEN_SQUARE_BRACKET; terminal CLOSE_SQUARE_BRACKET; /* Non-terminals */ non terminal program; non terminal explicit_value; non terminal const_array_list_value; /* Top level rules */ program ::= FCONST IDENTIFIER ASSIGN explicit_value ; explicit_value ::= OPEN_SQUARE_BRACKET const_array_list_value CLOSE_SQUARE_BRACKET | STRING_DEFINITION:e {: System.out.printf("explicit_value %s \n", e); :} ; const_array_list_value ::= explicit_value | const_array_list_value explicit_value ; 表,其中包含slides列。我想实现搜索。我在PostgreSQL中尝试了trigram索引。我创建了以下索引:

name

当我搜索至少3个字符时,索引工作正常:

CREATE INDEX index_slides_on_name_trigram ON slides USING gin (name gin_trgm_ops); 

但是当我的搜索短语短于3个字符时,没有使用索引:

explain analyze SELECT name FROM slides WHERE name ILIKE '%hur%';

QUERY PLAN                                                                
------------------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on slides  (cost=18.97..1809.80 rows=900 width=25) (actual time=0.810..6.316 rows=906 loops=1)
   Recheck Cond: ((name)::text ~~* '%hur%'::text)
   Heap Blocks: exact=583
   ->  Bitmap Index Scan on index_slides_on_name_trigram  (cost=0.00..18.75 rows=900 width=0) (actual time=0.552..0.552 rows=906 loops=1)
         Index Cond: ((name)::text ~~* '%hur%'::text)
 Planning time: 0.973 ms
 Execution time: 6.506 ms
(7 rows)

这是三元组索引的工作方式吗?我想知道有没有更好的方法来实现搜索。

1 个答案:

答案 0 :(得分:2)

PostgreSQL认为如果查询字符串太短,使用顺序扫描比使用trigram索引更有效。

这是因为短搜索字符串可能会找到很多结果,无论是否正确,如果您需要检查表格的较大部分,顺序扫描通常会更快。

您可以先运行

进行自我测试
SET enable_seqscan=off;

然后PostgreSQL会尽可能避免顺序扫描。

如果您不确定PostgreSQL是否正确,您可以在打开或关闭顺序扫描的情况下执行查询,并测量每种情况下需要多长时间。