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

因此,所有这些都表明需要考虑一个非常小的数据集。

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

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

  1. 根本不要尝试对此进行索引。只需使用ILIKE, LIKEonlower或类似的。(没有索引?)
  2. 使用 pg_trgm 索引以提高搜索速度。我会假设我需要以某种方式索引连接。
  3. 全文搜索。我认为这也将涉及连接索引。

不幸的是,我并不真正熟悉其中任何一个的预期性能或好处和权衡,因此很难知道我应该首先尝试哪些事情以及我什至不应该考虑哪些事情。我读过的一些内容表明,对 2 和 3 进行索引非常慢,这与我将偶尔进行修改的事实相冲突。并且混合语言使全文搜索看起来没有吸引力,因为它似乎是基于语言的,除非它可以同时处理多种语言。我是否会期望对于这么小的数据,一个简单的ILIKE或者一个LIKEonlower可能就足够快了?或者,对于这么小的数据修改的低负载,索引可能足够快?我会更好地寻找数据库之外的东西吗?

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

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

我在 PG 9.2.4 上,所以 9.3 之前的任何好东西都是一个选项。

4

2 回答 2

3

更新:我已将此答案扩展为详细的博客文章

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

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

radiata pinus

寻找:

pinus radiata

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

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

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

如果您主要搜索离散的单词并且词序并不重要,那么 Pg 的全文搜索与to_tsvectorandto_tsquery将是可取的。它支持左锚通配符搜索、加权、类别等。

如果您主要对离散列进行前缀搜索,那么LIKE对每列的常规 b-tree 索引进行简单查询将是可行的方法。

所以。弄清楚你需要什么,然后如何去做。你目前的不确定性可能部分源于对自己想要什么的真正了解。

于 2013-08-26T08:12:07.617 回答
1

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

关于使用 pg_trgm 的索引:您正在谈论对表的“偶尔”更新/插入。我认为使用三元组索引的额外成本只会在您更新/插入该表时出现- 比如每秒几次。

如果“偶尔”只意味着一小时几次(甚至更少),那么我怀疑你会在现实生活中看到差异。我认为在 Depesz 的 blob 中的某个地方也有一篇文章比较了使用和不使用三元索引的插入速度,但我再也找不到了。

于 2013-08-26T08:01:05.537 回答