LIKE 查询的最佳 Postgres 文本索引?

Tyl*_*ler 7 sql postgresql indexing gwt-gin sql-like

使用 Postgres 9.5,我有一张表addresses

CREATE TABLE addresses (
    id        integer PRIMARY KEY,
    address   text
);
Run Code Online (Sandbox Code Playgroud)

在那个表中,我有 750 万行。例子:

1, "1600 Pennsylvania Avenue NW, Washington, DC, 20500"

我在我的应用程序中使用这个表进行自动建议搜索,所以我需要使用这种类型的查询:

SELECT * FROM addresses WHERE address LIKE '123 Main St%';
Run Code Online (Sandbox Code Playgroud)

我创建了这个索引:

CREATE INDEX address_idx ON addresses (address);
Run Code Online (Sandbox Code Playgroud)

但问题是它需要大约 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)
Run Code Online (Sandbox Code Playgroud)

我尝试创建几种类型的gin索引,但它们要么没有效果,要么使查询变慢。我不确定我是否正确使用它们。

关于如何创建针对此类查询优化的索引的任何想法?


编辑

迄今为止找到的最佳解决方案是使用文本范围扫描:

SELECT *
FROM addresses
WHERE address >= '123 Main St' AND
      address <= concat('123 Main St', 'z');
Run Code Online (Sandbox Code Playgroud)

Gor*_*off 5

这是对between方法的详细说明,太长了,无法发表评论。

如果您使用标准 ASCII 字符,则可以使用波浪号技巧:

SELECT *
FROM addresses
WHERE address >= '123 Main St' AND
      address <= concat('123 Main St', '~');
Run Code Online (Sandbox Code Playgroud)

波浪号比其他字符具有更大的 ASCII 值。

我确实注意到 Postgres 也应该使用索引进行LIKE查询。我的猜测是问题与类型的兼容性有关。也许如果您将模式转换为 a varchar(),Postgres 将使用索引。