改进PostgreSQL中小数据文本搜索的好处和权衡

时间:2013-08-26 07:38:24

标签: performance postgresql search text

  • 我有4个感兴趣的文本列。
  • 每列最多约100个字符。
  • 3列中的文字主要是拉丁文字。 (数据是生物目录,这些是事物的名称。)
  • 目前数据约为500行。我预计这不会超过1000。
  • 少数用户(10岁以下)将具有添加,更新和删除数据的编辑权限。我不希望这些用户对数据库造成沉重负担。

所以这一切都表明需要考虑一个非常小的数据集。

我需要对所有4列执行搜索,其中至少有1列包含搜索文本(不区分大小写)。查询将通过Web应用程序发布(并提供结果)。我对如何接近它感到有些迷茫。

PostgreSQL提供了一些提高文本搜索速度的选项。我一直在考虑的PostgreSQL内置的可能选项是

  1. 不要试图对此进行索引。只需在ILIKE上使用LIKElower或类似内容即可。 (没有索引?)
  2. 使用pg_trgm进行索引以提高搜索速度。我会假设我需要以某种方式索引连接。
  3. 全文搜索。我认为这也会涉及连接索引。
  4. 不幸的是,我并不是很熟悉这些中的任何预期表现或其中的好处和交易,因此很难知道我应该先尝试哪些事情以及我甚至不应该考虑哪些事情。我读过的一些内容表明,对2和3进行索引非常慢,这与我偶尔会进行修改的事实相冲突。混合语言使全文搜索看起来没有吸引力,因为它似乎是基于语言的,除非它可以同时处理多种语言。我希望数据这么小,ILIKELIKElower上的{{1}}可能足够快吗?或者索引速度足够快,以便对数据进行少量修改?我会更好地寻找数据库之外的东西吗?

    当然,我必须对所有这些进行基准测试才能确定最快速,但不幸的是,我没有太多时间进行这个项目。那么这些方法的好处和权衡是什么?这些选项中哪些不适合解决此类问题?有哪些其他类型的解决方案(包括可能在数据库之外)值得考虑?

    (我想我可能会发现某些初学者关于PG中文本搜索的教程很有用,但我的搜索大部分都是全文搜索,我甚至不知道它对我有用。)

    我正在使用PG 9.2.4,因此9.3之前的任何好东西都是可选的。

2 个答案:

答案 0 :(得分:3)

更新:我已将此答案扩展为a detailed blog post

请不要仅仅关注速度,而应首先考虑搜索语义。定义您的要求。

例如,用户是否需要能够根据条款的顺序进行区分?应

radiata pinus

查找

pinus radiata

?相同的规则是否适用于列中的单词与列之间的单词?

空格总是单词分隔符,还是搜索词的列部分中的空格?

你需要通配符吗?如果是这样,你是否只需要左锚定的通配符(想想staph%)或者你是否也需要右锚定或中缀通配符(%ccusp%s)?只有pg_tgrm才能帮助您使用中缀通配符。后缀通配符可以通过单词reverse()上的索引来处理,但这很快就会变得笨拙,所以在实践中pg_tgrm是最好的选择。

如果您主要搜索离散词并且词序不重要,则需要使用to_tsvectorto_tsquery进行Pg的全文搜索。它支持左锚定通配符搜索,加权,类别等。

如果您主要对离散列进行前缀搜索,那么对每列的常规b树索引进行简单的LIKE查询将是最佳选择。

因此。弄清楚你需要什么,然后如何做到这一点。你目前的不确定性可能部分原因在于并不完全清楚自己想要什么。

答案 1 :(得分:1)

对于1000行,我猜想LIKElower()一起应该足够快。经过几次查询后,表格很可能会被完全缓存。

关于使用pg_trgm进行索引:您正在谈论对表的“偶尔”更新/插入。我认为使用trigram索引的额外成本只会在您更新/插入表很多时显示 - 就像每秒几次一样。

如果“偶尔”只意味着每小时几次(甚至更少),那么我怀疑你会看到现实中的差异。我觉得在Depesz的blob中有一篇文章还有一篇文章比较了插入速度有没有三元组索引,但我再也找不到了。