Sql 有效地查询包含子字符串的列

Sql 有效地查询包含子字符串的列,sql,postgresql,indexing,Sql,Postgresql,Indexing,给定一个值类似于/123/12/34/56/5/的字符串列,查询包含给定数字的所有记录的最佳方式是什么(例如12) 我想到的解决办法是: 从things.path中选择id,如“%/12/%” 但是,由于前导的%,因此此查询无法在列上使用索引 一定有更好的。这是什么 使用PostgreSQL,但更希望使用能够跨其他数据库工作的解决方案。在PostgreSQL 9.1中,您可以利用并使用它构建GIN索引 CREATE EXTENSION pg_trgm; -- once per databas

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

我想到的解决办法是:


从things.path中选择id,如“%/12/%”

但是,由于前导的
%
,因此此查询无法在列上使用索引

一定有更好的。这是什么


使用PostgreSQL,但更希望使用能够跨其他数据库工作的解决方案。

在PostgreSQL 9.1中,您可以利用并使用它构建GIN索引

CREATE EXTENSION pg_trgm; -- once per database

CREATE INDEX things_path_trgm_gin_idx ON things USING gin (path gin_trgm_ops);
您的
LIKE
表达式可以使用此索引,即使它没有左锚定

请参阅详细信息


不过,如果可以的话,请对其进行规范化。

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

'/123/12/34/56/5/' becomes ARRAY[123,12,34,56,5]
因此,
path\u arr
是类型为
INTEGER[]
的列,然后可以在该列上创建GIN索引:

CREATE INDEX ON things USING gin(path_arr);
对包含12的所有项目的查询将变为:

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

SELECT*FROM things WHERE ARRAY[12]最好不要有一个多值字段:)我可以使用包含路径的附加表'thing_paths'。然后连接它并查询它~
从thing\u path上的things内部连接thing\u路径中选择DISTINCT things.id。thing\u id=things.id WHERE thing.path,如“/12/%”
。但在这个阶段,这比我理想中想要做的要多。谢谢。很高兴知道。尽管如此,写入性能仍然显著降低。请重新规范化。这个专栏几乎只在一两个地方使用,还不确定标准化是否值得。重新规范化:规范化表单可能会更快。谢谢。这是另一种选择。但是,从技术上讲,它与埃尔文建议的类似于GIN指数,只是表达方式不同而已。它是另一个GIN指数。但它更接近实际数据。原则上,索引将更有效,因为它不会记录包含“27/”和“1/2”等内容的项目。Edmund,我接受Erwin的答案只是因为它更简单(不需要更改任何代码)。但我希望我能接受两个答案,因为你的解决方案更优雅。在务实和优雅之间经常有一个折衷。而列表上索引的语法也没有帮助,所以我可能也选择了Erwin的答案(tbh)。谢谢你的评论。
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)