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)