Postgres在第一次查询时的性能研究

时间:2015-06-01 14:45:49

标签: performance postgresql indexing full-text-search ispell

我们正在使用自定义文本搜索配置在德语文本中搜索以获得对复合词的正确支持。

字典可以在这里找到:http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/(ispell-german-compound.tar.gz)。

dicts转换为UTF8,我使用以下脚本将配置添加到数据库中:

DROP TEXT SEARCH DICTIONARY IF EXISTS german_bon_ispell CASCADE;
DROP TEXT SEARCH DICTIONARY IF EXISTS german_bon_stem CASCADE;

CREATE TEXT SEARCH CONFIGURATION german_bon (copy=german);

CREATE TEXT SEARCH DICTIONARY german_bon_stem (
TEMPLATE = snowball,
  Language = german,
  StopWords = german
);

CREATE TEXT SEARCH DICTIONARY german_bon_ispell (
TEMPLATE = ispell,
  dictfile = german,
  afffile = german,
  StopWords = german
);

ALTER TEXT SEARCH CONFIGURATION german_bon
  ALTER MAPPING FOR
    asciiword,word,numword,numhword,hword_asciipart,hword_part,hword_numpart
  WITH german_bon_ispell, german_bon_stem;

字典本身效果很好,但在每个新的连接/会话中,使用此配置的第一个查询需要1-2个秒。每次跟随~1-3ms。

这种效果在英语词典中也是可以观察到的,但不是那么激烈:

db=# \timing
Timing is on.
db=# select ts_debug('english', 'Book');
                               ts_debug
-----------------------------------------------------------------------
 (asciiword,"Word, all ASCII",Book,{english_stem},english_stem,{book})
(1 row)

Time: 6,977 ms
db=# select ts_debug('english', 'Book');
                               ts_debug
-----------------------------------------------------------------------
 (asciiword,"Word, all ASCII",Book,{english_stem},english_stem,{book})
(1 row)

Time: 2,258 ms
db=# select ts_debug('german_bon', 'Buch');
                                             ts_debug
---------------------------------------------------------------------------------------------------
 (asciiword,"Word, all ASCII",Buch,"{german_bon_ispell,german_bon_stem}",german_bon_ispell,{buch})
(1 row)

Time: 916,286 ms
db=# select ts_debug('german_bon', 'Buch');
                                             ts_debug
---------------------------------------------------------------------------------------------------
 (asciiword,"Word, all ASCII",Buch,"{german_bon_ispell,german_bon_stem}",german_bon_ispell,{buch})
(1 row)

Time: 1,240 ms
db=#

我目前唯一知道的是使用持久连接/连接池,我们正在使用pgbouncer。但这引入了客户端(PHP> PDO> Doctrine)的一些其他问题,这看起来像是一个缓存问题。

有没有办法减少这个"启动时间"?看起来有点像为每个新连接加载/创建配置,这看起来并不合理。

1 个答案:

答案 0 :(得分:2)

已知问题 - 加载ispell字典很慢(每次在会话中第一次使用字典时加载它)。一个很好的解决方案是会话池。其他解决方案是使用共享的ispell字典 - 由Tomas Vondra编写的扩展 - shared_ispell,但我不知道PostgreSQL 9.2及更高版本的新版本是如何得到支持的 - 它在9.2上进行了测试。德语可能有问题 - 用捷克语测试。

其他可能性是使用德国雪球词典 - 它应该明显更快 - 但结果可能会更糟。从您的全文配置中删除german_bon_ispell。