我有2个表1,具有数百万个记录,另一个具有200k。我正在尝试使用几个串联的列进行UTL匹配,但是当然,此过程将花费大量时间(比较每条记录数百万次)。 x.code只是比较table1的另一个要求 有什么办法可以加快速度吗?比较100行花了18分钟
select *
from table1 x
where exists(select *
from largetable y
where x.state = y.state and
utl_match.jaro_winkler_similarity(x.address || ' ' || x.city, y.address || ' ' || y.city) > 95 and
x.code like '%a%'
);
答案 0 :(得分:2)
您正在进行距离匹配。通过这种逻辑,可以索引的字段之间必须存在一些相似性。查找一些产生可索引结果的函数,并将其用于每一行的搜索空间。
例如,您有一个City
字段-大多数标准化的城市名称将完全匹配(并且您可以将城市的不同值标准化到单独的表格中以解决拼写错误)。进行城市匹配后,您可能会大大减少地址的搜索空间。
如果这还不够,请产生三个“匹配”键,分别是地址第一个单词的前两个字母字符,地址第一个单词的后两个字母字符,地址中存在的数字。在考虑编辑距离之前,请使用三个“匹配”键作为风选功能。
例如,将“ 123 Mulberry lane”匹配到“ 123 Mlberry ln”,步骤将是:
123 Mulberry Lane -> { numbers: '123', first: 'MU', last: 'RY' }
123 Mlberry Ln -> { numbers: '123', first: 'ML', last: 'RY' }
因此,尽管第一个字符winnow会导致不考虑地址-数字和最后的启发式方法仍然可以捕获该地址。
答案 1 :(得分:0)
编辑距离匹配会生成每行相对于其他行的矩阵,因此没有可以索引的内容。您所要做的就是减少需要比较的记录集。
有什么办法可以加快速度吗?
性能调优是一门科学。如果没有更多有关数据偏斜和分布的详细信息,我们只能做一些猜测。
x.code只是比较table1的另一个要求
因此,随机猜测:将其包含在外部查询中可能是一个好主意。
select *
from table1 x
where x.code like '%a%'
and exists(select *
from largetable y
where x.state = y.state and
utl_match.jaro_winkler_similarity(x.address || ' ' || x.city, y.address || ' ' || y.city) > 95
);
另一种随机猜测。即使largetable.state
被索引了,它也可能不是非常有效的访问路径,因此,(半)交叉联接可能更有效:
select distinct t1.*
from table1 x
join largetable y
on x.state = y.state
where x.code like '%a%'
and utl_match.jaro_winkler_similarity(x.address || ' ' || x.city, y.address || ' ' || y.city) > 95
;
这就是为什么诸如SOUNDEX()或Metaphone之类的技术很方便的原因:它们提供了可用于等式运算并可以建立索引的近似值。但是,它们很粗糙,对于某些错别字尤其无法原谅,因此这就是我们也需要其他算法的原因。但是也许您可以实施多步骤方法,使用标记化方法来识别一些匹配项并编辑距离以获胜其余部分。