我们使用自定义文本搜索配置来搜索德语文本,以获得对复合词的适当支持。
字典可以在这里找到: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。但这也会给out-client带来一些其他问题(PHP>PDO>docine),看起来像是一个缓存问题。
有什么办法可以减少这种“启动时间”?看起来配置是为每个新连接加载/创建的,这似乎不合理。
最佳答案
众所周知,问题是加载ispell字典很慢(每次在会话中首次使用字典时都会加载)。一个好的解决方案是会话池。另一个解决方案是使用共享的ispell字典-由Tomas Vondra编写的扩展-shared_ispell,但我不知道一些新版本的PostgreSQL 9.2和更高版本有多受支持-它是在9.2上测试的。德语可能有问题——它是用捷克语测试的。
另一种可能是使用德语雪球词典-应该会快得多-但结果可能更糟。从全文配置中删除德语ispell。