postgresql SQL选择文本字段中包含子字符串的行

pgky5nke  于 2023-08-04  发布在  PostgreSQL
关注(0)|答案(1)|浏览(137)

我有一个CLIENTS_WORDS表,表中的列是:Postgresql数据库中的ID、CLIENT_ID、WORD

ID|CLIENT_ID|WORD
1 |1242     |word1
2 |1242     |WordX.foo
3 |1372     |nextword
4 |1999     |word1

字符串
在这个表中可能有大约100 k-500 k行。
我有这样的查询字符串:

'Some people tell word1 to someone'
'Another stringWordX.foo too possible'


我希望从查询字符串中包含WORD列文本的表中选择 *。
现在我使用select

select * from CLIENTS_WORDS
where strpos('Some people tell word1 to someone', WORD) > 0


我的问题是,检索匹配行的最佳性能/快速方法在哪里?

a6b3iqyw

a6b3iqyw1#

使用unnest()和JOIN可以获得更好的性能。就像这样:

SELECT DISTINCT c.client_id
FROM   unnest(string_to_array('Some people tell word1 ...', ' ')) AS t(word)
JOIN   clients_words c USING (word);

字符串
查询的详细信息取决于缺少的需求详细信息。这是在 space 字符处拆分字符串。
一个更灵活的工具是regexp_split_to_table(),在这里你可以使用字符类或缩写作为分隔符。喜欢的:

regexp_split_to_table('Some people tell word1 to someone', '\s') AS t(word)
regexp_split_to_table('Some people tell word1 to someone', '\W') AS t(word)

当然,clients_words.word列需要索引以提高性能:

CREATE INDEX clients_words_word_idx ON clients_words (word)


会很快。

忽略词边界

如果你想完全忽略单词边界,整个事情就会变得更加昂贵。LIKE/ILIKE与三元GIN指数的组合会出现在脑海中。请参阅:

然而,你的情况是倒退,索引不会有帮助。你必须检查每一行的部分匹配,这使得查询非常昂贵。上级的方法是 * 反转 * 操作:拆分单词然后搜索。

相关问题