LIKE查询的最佳Postgres文本索引?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LIKE查询的最佳Postgres文本索引?相关的知识,希望对你有一定的参考价值。
使用Postgres 9.5,我有一张桌子addresses
。
CREATE TABLE addresses (
id integer PRIMARY KEY,
address text
);
在那张表中,我有750万行。例:
1, "1600 Pennsylvania Avenue NW, Washington, DC, 20500"
我在我的应用程序中使用此表进行自动搜索,因此我需要使用此类查询:
SELECT * FROM addresses WHERE address LIKE '123 Main St%';
我创建了这个索引:
CREATE INDEX address_idx ON addresses (address);
但问题是它需要大约1秒,这太慢了。
这是查询计划:
EXPLAIN SELECT * FROM addresses WHERE address LIKE '123 Main St%';
----
Seq Scan on addresses (cost=0.00..161309.76 rows=740 width=41)
Filter: (address ~~ '123 Main St%'::text)
我尝试创建几种类型的gin
索引,但它们要么没有效果,要么使查询速度变慢。我不确定我是否正确使用它们。
有关如何创建针对此类查询优化的索引的任何想法?
编辑
到目前为止找到的最佳解决方案是使用文本范围扫描:
SELECT *
FROM addresses
WHERE address >= '123 Main St' AND
address <= concat('123 Main St', 'z');
答案
这是关于between
方法的详细说明,对于评论来说太长了。
如果您使用的是标准ASCII字符,则可以使用代字号技巧:
SELECT *
FROM addresses
WHERE address >= '123 Main St' AND
address <= concat('123 Main St', '~');
Tilde的ASCII值比其他字符大。
我注意到Postgres也应该使用LIKE
查询的索引。我的猜测是问题与类型的兼容性有关。也许如果你将模式转换为varchar()
,Postgres会使用索引。
另一答案
你可以尝试三件事:
- 如果您的数据库位于'
C
'区域设置(您可以在l
提示符下使用psql
检查),那么常规的Btree
索引应该有助于优化LIKE 'abc%'
类型的查询。 - 如果没有,您可以在创建
Btree
索引时尝试使用合适的运算符类。对于例如CREATE INDEX tbl_col_text_pattern_ops_idx ON tbl(col text_pattern_ops);
- 如果这不起作用,你也可以尝试使用
GiST / GIN
,更多细节给予here。
如果你想了解更多,你应该阅读Erwin的StackOverflow答案here,详细说明不同的Postgres索引如何与LIKE
/ ILIKE
一起使用。
以上是关于LIKE查询的最佳Postgres文本索引?的主要内容,如果未能解决你的问题,请参考以下文章