PostgreSQL,查找差异为n个字符的字符串
假设我有一张这样的桌子PostgreSQL,查找差异为n个字符的字符串,sql,postgresql,indexing,pattern-matching,Sql,Postgresql,Indexing,Pattern Matching,假设我有一张这样的桌子 id data 1 0001 2 1000 3 2010 4 0120 5 0020 6 0002 id是主键,data是固定长度的字符串,其中字符可以是0、1、2 有没有一种方法可以建立索引,这样我就可以快速找到与给定字符串相差n个字符的字符串?比如字符串0001和n=1我想得到第6行 谢谢。这是附加模块提供的功能。它完全符合您的要求: SELECT * FROM a WHERE levenshtein(data, '1110') =
id data
1 0001
2 1000
3 2010
4 0120
5 0020
6 0002
id
是主键,data
是固定长度的字符串,其中字符可以是0、1、2
有没有一种方法可以建立索引,这样我就可以快速找到与给定字符串相差n个字符的字符串?比如字符串0001
和n=1
我想得到第6行
谢谢。这是附加模块提供的功能。它完全符合您的要求:
SELECT *
FROM a
WHERE levenshtein(data, '1110') = 1;
但它不是很快。使用大表时速度较慢,因为它不能使用索引
使用附加模块提供的相似性或距离运算符,您可能会有收获。这些可以使用链接手册页面中详细说明的三元索引。我没有取得任何进展,模块使用了不同的“相似性”定义
总的来说,这个问题似乎符合实际情况
如果您的案例与问题中的示例一样简单,您可以将LIKE
与trigram GIN索引结合使用,这对于大表来说应该相当快:
SELECT *
FROM a
WHERE data <> '1110'
AND (data LIKE '_110' OR
data LIKE '1_10' OR
data LIKE '11_0' OR
data LIKE '111_');
选择*
从
其中数据“1110”
和(数据如“_110”或
数据如“1_10”或
类似“11_0”或
数据如“111"”;
显然,如果字符串较长且差异大于1
,这种技术很快就变得不可行
但是,由于字符串很短,任何查询都会匹配相当大比例的基表。因此,指数支持几乎不会给你买任何东西。大多数情况下,Postgres按顺序扫描会更快
我测试了10k和100k行,有和没有三角图索引。由于约19%符合给定测试用例的标准,因此顺序扫描速度更快,
levenshtein()
仍然获胜。对于匹配少于约5%行(取决于)的更具选择性的查询,使用索引的查询速度更快。对于n=1
您应该只找到第6行。第2行和第5行在两个地方不同。哎呀,更正了,谢谢@Erwinbrandstetter如果n=2,那么ID将是3和4?@Roms应该是5和2是的,我想是关于levenshtein的,但我想它不是很快:(我现在正在检查三联图。)