2

给定一个值类似于 的字符串列/123/12/34/56/5/,查询包含给定数字12例如)的所有记录的最佳方法是什么?

我头脑中的解决方案是:

SELECT id FROM things WHERE things.path LIKE '%/12/%'

但是 AFAIK 由于前导,此查询不能在列上使用索引%

一定有更好的东西。它是什么?

使用 PostgreSQL,但更喜欢适用于其他数据库的解决方案。

4

2 回答 2

4

如果您愿意将该列转换为整数数组,例如:

'/123/12/34/56/5/' becomes ARRAY[123,12,34,56,5]

path_arr是一个 type 的列INTEGER[],那么您可以在该列上创建一个 GIN 索引:

CREATE INDEX ON things USING gin(path_arr);

包含 12 的所有项目的查询然后变为:

SELECT * FROM things WHERE ARRAY[12] <@ path_arr;

这将使用索引。在我的测试中(有一百万行),我得到如下计划:

EXPLAIN SELECT * FROM things WHERE ARRAY[12]  <@ path_arr;
                                      QUERY PLAN
----------------------------------------------------------------------------------------
 Bitmap Heap Scan on things  (cost=5915.75..9216.99 rows=1000 width=92)
   Recheck Cond: (path_arr <@ '{12}'::integer[])
   ->  Bitmap Index Scan on things_path_arr_idx  (cost=0.00..5915.50 rows=1000 width=0)
         Index Cond: ('{12}'::integer[] <@ path_arr)
(4 rows)
于 2012-04-16T04:59:42.047 回答
3

在 PostgreSQL 9.1 中,您可以使用该pg_trgm模块并使用它构建 GIN 索引。

CREATE EXTENSION pg_trgm; -- once per database

CREATE INDEX things_path_trgm_gin_idx ON things USING gin (path gin_trgm_ops);

LIKE即使不是左锚,您的表达式也可以使用此索引。

请在此处查看 depesz的详细演示。

但是,如果可以,请对其进行规范化。

于 2012-04-16T03:57:39.397 回答