PostgreSQL 中连接名和姓的搜索优化

Posted

技术标签:

【中文标题】PostgreSQL 中连接名和姓的搜索优化【英文标题】:Optimization of search on concatenated firstname and lastname in PostgreSQL 【发布时间】:2015-08-05 07:28:02 【问题描述】:

我在 Postgres 中编写了一个 SQL 查询,它通过名字和姓氏来搜索用户。我的问题只是它是否可以优化,因为它会被大量使用。

CREATE INDEX users_firstname_special_idx ON users(firstname text_pattern_ops);
CREATE INDEX users_lastname_special_idx ON users(lastname text_pattern_ops);

SELECT id, firstname, lastname FROM users WHERE firstname || ' ' || lastname ILIKE ('%' || 'sen' || '%') LIMIT 25;

如果我运行解释,我会得到以下输出:

Limit  (cost=0.00..1.05 rows=1 width=68)
  ->  Seq Scan on users  (cost=0.00..1.05 rows=1 width=68)
        Filter: (((firstname || ' '::text) || lastname) ~~* '%sen%'::text)

据我了解,我应该尝试让 postgrep 跳过“过滤器:”-thing。对吗?

希望大家有什么建议。

干杯。

【问题讨论】:

不要连接两个名称元素,单独过滤它们,也不要使用双端通配符。如果以这种方式过滤,无论创建多少索引,它们都将无法使用。 你检查过postgres全文搜索吗? 是的,但老实说,我发现文本搜索有点“令人困惑”。我现在尝试了几种方法,但我似乎无法让搜索使用索引,除非我使用一列连接名称创建一个物化视图并在该列上放置一个索引。然而,这并不聪明,因为我需要经常刷新视图,并且我希望表格有几千行。 【参考方案1】:

如果字符串中有多个% 通配符,则需要使用trigram index。

但是,在您的情况下,您正在做一些奇怪的事情。您将firstnamelastname 连接起来,中间有一个空格。因此,搜索字符串“%sen%”出现在 firstnamelastname 中,并且从不包含空格。因此,更好的解决方案是:

CREATE INDEX users_firstname_special_idx ON users USING gist (firstname gist_trgm_ops);
CREATE INDEX users_lastname_special_idx ON users USING gist (lastname gist_trgm_ops);

SELECT id, firstname || ' ' || lastname AS fullname
FROM users
WHERE firstname ILIKE ('%sen%') OR lastname ILIKE ('%sen%')
LIMIT 25;

【讨论】:

感谢您的回答。我确实使用了这个空间,这样我就可以在我网站的搜索字段中写下全名(名字和姓氏)。因此,如果用户名为 Jack Jones,我实际上可以写“Jack Jones”或“Jack Jo”,他会出现在结果中。这样,我不只是搜索名字或姓氏。 然后在选择列表中进行连接并搜索各个字段;查看更新的答案。 谢谢!你是我最好的新朋友。 :) 使用“EXPLAIN”时,我从 460 到 8.3 的成本对包含 10.000 行的用户表进行测试!非常感谢! 嗯,但是如果我把全名写成“lastname ILIKE ('%Tristan Larson%')”这样的全名,这仍然行不通 总是很高兴有一个新的好朋友!如果您搜索问题中的短语,请使用我建议的方法。如果您搜索全名,那么您应该寻找(不区分大小写)相等性(例如,没有通配符)。您可以在firstname || ' ' || lastname 上创建索引以加快速度。请记住,您创建索引以匹配搜索。【参考方案2】:

您完全从 PostgreSQL 文档中描述了情况:

Indexes on Expressions

【讨论】:

以上是关于PostgreSQL 中连接名和姓的搜索优化的主要内容,如果未能解决你的问题,请参考以下文章

text 调整作者名和姓顺序

数值算法:无约束优化之一维搜索方法之多维优化问题中每步迭代的最优学习率设定问题

单目标优化求解基于matlab秃鹰算法(BES)求解最优目标问题含Matlab源码 1546期

MATLAB教程案例97基于GA遗传优化的CNN卷积神经网络最优训练参数搜索matlab仿真

R语言使用quantile函数计算评分值的分位数(20%40%60%80%)使用逻辑操作符将对应的分位区间(quantile)编码为分类值生成新的字段strsplit函数将学生的名和姓拆分

单目标优化求解基于matlab粒子群混沌混合蝴蝶优化算法求解最优目标问题(HPSOBOA)含Matlab源码 1538期