lat*_*lip 4 sql postgresql indexing pattern-matching sql-like
我很欣赏LIKE查询很慢,因为它们无法编入索引.但是,我很好奇在这种情况下的性能影响:
说我有一个像这样的表:
user_id | message
-------------------
1 | foo bar baz
1 | bar buz qux
. . .
. . .
2 | bux bar foo
2 | bar
Run Code Online (Sandbox Code Playgroud)
我说100万行,但有10,000个用户,所以每个用户有大约100条消息.
显然搜索如下:
SELECT * FROM table WHERE message like '%ar%';
Run Code Online (Sandbox Code Playgroud)
会很慢.但是在我的应用程序中,我只会搜索用户的消息:
SELECT * FROM table WHERE message like '%ar%' AND user_id = 2;
Run Code Online (Sandbox Code Playgroud)
其中user_id列将被索引.
我是否正确地认为在这样的场景中,Postgres只会在使用索引的user_id列而不是完整的表后对用户~100行执行慢LIKE查询 - 从而限制了我的性能损失?
而且只要任何一个用户只有大约100条消息,这样的查询对于10或1亿用户来说不会明显变慢?
@MatBailie已经清除了你的主要问题.我想解决你的断言:
我很欣赏LIKE查询很慢,因为它们无法编入索引.
这不完全正确.
首先,这已经很久了,左锚定模式 可以使用索引.这适用于正则表达式(~)以及LIKE(~~)和SIMILAR TO.我最近在dba.SE上写了一篇关于此事的综合评论:
这可能对您不起作用,因为问题中的模式没有锚定.如果是这样,您可以使用多列索引获得优化性能,该索引使用列的 文本模式运算符类text_pattern_ops,message如下所示:
CREATE INDEX tbl_user_id_message_idx ON tbl (user_id, message text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)
对于以下查询:
SELECT *
FROM tbl
WHERE user_id = 2
AND message ~~ 'bar%'; -- left anchored LIKE
Run Code Online (Sandbox Code Playgroud)
其次,从PostgreSQL 9.1开始,你可以使用pg_trgm扩展并用它创建一个GIST或GIN索引,所有模式都可以使用.一些限制适用.维护这样的索引更加昂贵,因此对于只读或很少编写的表最有用.细节:
Depesz有一个相关的教程.
| 归档时间: |
|
| 查看次数: |
3508 次 |
| 最近记录: |