Mysql 如何优化此Levenshtein距离计算

Mysql 如何优化此Levenshtein距离计算,mysql,levenshtein-distance,Mysql,Levenshtein Distance,表a约有8000行,表b约有250000行。如果没有levenshtein函数,查询只需不到2秒钟。包括该功能后,大约需要25分钟 SELECT * FROM library a, classifications b WHERE a.`release_year` = b.`year` AND a.`id` IS NULL AND levenshtein_ratio(a.title, b.title) >

表a
约有8000行,
表b
约有250000行。如果没有
levenshtein
函数,查询只需不到2秒钟。包括该功能后,大约需要25分钟

SELECT
      *
   FROM
      library a,
      classifications b
   WHERE  
      a.`release_year` = b.`year`
      AND a.`id` IS NULL
      AND levenshtein_ratio(a.title, b.title) > 82

我假设
levenshtein_ratio
是您编写的函数(或者可能包含在其他地方)。如果是这样的话,数据库服务器将无法在使用索引的正常意义上对此进行优化。因此,这意味着它只需要为其他连接条件产生的每个记录调用它。对于内部联接,这些表的大小可能会非常大(最大值为8000*250000=20亿)。您可以使用以下命令检查需要调用它的总次数:

SELECT
      count(*)
   FROM
      library a,
      classifications b
   WHERE  
      a.`release_year` = b.`year`
      AND a.`id` IS NULL

这就是为什么它很慢的原因(并不是如何优化它的问题的答案)。要优化它,您可能需要向联接条件添加额外的限制因素,以减少对用户定义函数的调用次数。

更改查询以使用正确的联接(自1996年以来,语法一直存在)

此外,您的所有levensrein条件都可能被移动到join条件中,这将为您带来性能优势:

SELECT *
FROM library a
JOIN classifications b
    ON a.`release_year` = b.`year`
    AND levenshtein_ratio(a.title, b.title) > 82
WHERE a.`id` IS NULL
此外,确保b年有一个指数:

create index b_year on b(year);

你提供的信息太少,无法真正帮助你

1) 我的第一个猜测是尝试创建其他WHERE条件,以减少要扫描的行数

2) 如果这是不可能的…鉴于表库和分类中的标题是已知的,一个想法是创建一个表,其中所有数据都已按如下方式计算:

TABLE levenshtein_ratio
id_table_library
id_table_classifications
precalculated_levenshtein_ratio
因此,您可以使用以下查询填充表:

insert into levenshtein_ratio select a.id, b.id, levenshtein_ratio(a.title, b.title) from library, classifications
然后您的查询将是:

    SELECT
          *
       FROM
          library a LEFT JOIN 
          classifications b ON a.`release_year` = b.`year`

LEFT JOIN levenshtein_ratio c ON c.id_table_library = a.id AND c.id_table_classifications = b.id
       WHERE  
          a.`id` IS NULL
          AND precalculated_levenshtein_ratio > 82
这个查询可能不会超过原来的2秒


此解决方案的问题在于,表a和表b中的数据可能会更改,因此您需要创建一个触发器以保持其更新。

显然,我不知道您使用的是什么levenshtein算法,但您可以尝试优化levenshtein距离和