【问题标题】:Indexing strategy for full text search in a multi-tenant PostgreSQL database多租户 PostgreSQL 数据库中全文搜索的索引策略
【发布时间】:2012-09-19 09:24:35
【问题描述】:

我有一个 PostgreSQL 数据库,用于存储多个用户帐户的联系信息表(名字、姓氏)。每个联系人行都有一个用户 ID 列。设置索引以便用户可以搜索他们的联系人名字或姓氏的几个字母的最高效的方法是什么?

我知道传统的 b-tree 索引和特定于 PG 的 GIN 和 GiST,但我只是不确定它们如何(或不能)一起工作,这样只有几个联系人的用户不会在按 user_id 过滤之前必须搜索所有联系人。

【问题讨论】:

  • 可能是 dba.SE 的有趣候选者(以及一些格式使其更易于阅读)。

标签: postgresql full-text-search multi-tenant


【解决方案1】:

您应该将帐户标识符添加为您创建的任何索引的第一列。这实际上将首先将搜索范围缩小到属于该帐户的行。对于 gist 或 gin 全文索引,您需要安装 btree_gist 或 btree_gin 扩展。

如果您只需要搜索第一个字母,最简单且可能最快的方法是使用支持两列文本操作的常规 btree 并进行 2 次查找。您需要使用 text_pattern_ops opclass 来支持文本前缀查询并使用 lower() 字段来确保不区分大小写:

CREATE INDEX contacts_firstname_idx ON contacts(aid, lower(firstname) text_pattern_ops);
CREATE INDEX contacts_lastname_idx ON contacts(aid, lower(lastname) text_pattern_ops);

查询将如下所示:

SELECT * FROM contacts WHERE aid = 123 AND
    (lower(firstname) LIKE 'an%' OR lower(lastname) LIKE 'an%')

【讨论】:

  • 我担心搜索要求可能会扩大到包括职位、公司名称等内容。所以可能是一个额外的文本列,通过触发器或应用回调填充空格分隔的字符串以包含在从其他列搜索,可用于减少用户 id 和该列的单个索引。
  • 在这种情况下,全文索引方法可能会更好。如果停用词限制不是问题,只需在字段连接上创建索引并使用 to_tsquery('searchprefix:*')。如果您不仅希望能够从单词的开头进行搜索,请查看 pg_trgm。
猜你喜欢
  • 1970-01-01
  • 2016-09-07
  • 1970-01-01
  • 2011-12-30
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2018-07-22
相关资源
最近更新 更多