UTL_MATCH性能

时间:2018-07-31 18:11:26

标签: sql oracle

我有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%'
            );

2 个答案:

答案 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之类的技术很方便的原因:它们提供了可用于等式运算并可以建立索引的近似值。但是,它们很粗糙,对于某些错别字尤其无法原谅,因此这就是我们也需要其他算法的原因。但是也许您可以实施多步骤方法,使用标记化方法来识别一些匹配项并编辑距离以获胜其余部分。