mysql - 加速 levenshtein 查询
问题描述
我有一个大约 100 万条记录的多用户数据库管理系统,其结构如下:
- 后端(MySQL)
- “DNames”表
- “全名”字段
- “身份证”字段
- “DNames”表
- 前端(MS 访问)
- "levenshtein"函数
- “列夫”查询
- “lev_dist” 字段(使用上面的函数计算的 levenshtein 距离,按 asc 排序)
- “全名”字段
- “身份证”字段
- “结果”形式的“srch”文本框
我的问题是,当我运行查询(即使用“srch”文本框)而不进行排序时,它的速度足够快,但是当我使用排序时,大约需要 30 到 90 秒才能完成(取决于电脑规格)。我需要排序操作来找到“srch”文本框中的文本与数据库之间的前 10 个(最接近的)匹配项,那么如何加快处理速度?有没有办法让它达到最大 5 秒?此过程可以同时从 5 台 PC 上运行。我尝试使用 MySQL levenshtein函数,但花了 2 分钟!
解决方案
你会接受妥协吗?在大约 1 毫秒内找到“小”距离内的所有单词(如果数据缓存在 buffer_pool 中)?
- 建立一个大约有 5M-10M 行的表格(基于你的 1M 'words')。它将有两列——F(word),word。
- 查找 F(word) 以获取可能的单词列表。
F(word) 是一组字符串——取出“单词”并删除每个字母,加上原始单词。例如:
word --> ord, wrd, wod, wor, word
letter --> etter, ltter, leter, lettr. lette, letter
(注意“字母”出现两次)
表和查询:
CREATE TABLE ricks_leven ()
fword VARCHAR(22) NOT NULL, -- F(word)
word VARCHAR(22) NOT NULL, -- the desired word
PRIMARY KEY(fword, word)
) ENGINE=InnoDB;
SELECT word, COUNT(*) AS ct
FROM ricks_leven
WHERE fword IN ('etter', 'ltter', 'leter', 'lettr'. 'lette', 'letter')
GROUP BY word
ORDER BY ct DESC
LIMIT 10;
完美匹配将自动出现在输出的首位。接下来可能会出现一些其他“可能”的拼写错误。我不知道 Levenshtein 距离是否以相同的方式排序结果。
该算法涵盖了这些常见的错别字,所有这些错别字都有一个小的 Levenshtein 距离:
- 任何一个字母的下降,
- 相邻字母转置(距离=2,但很重要),
- 在任何位置添加的字母。
速度和完整性之间的折衷:
- 用我的技术。如果你得到一些结果,然后退出。
- 回到缓慢的 Levenshtein 搜索。
推荐阅读
- sql - IF 函数格式 SQL 出错:不支持错误 BOOL、STRING、BOOL,仅 IF(BOOL、ANY、ANY)
- python - 如何让自定义 QCompleter 与自定义项目委托一起使用?
- java - java - 如何在java中将String对象/变量表示为数组变量名?
- c# - 在已注册的 .NET 数据提供程序列表中找不到指定的不变名称“MySql.Data.MySqlClient”
- php - 缓存引擎搜索未正确配置 Cakephp 2.4.3
- amazon-web-services - aws 在提到的时间段内下载所有自定义时间云手表日志
- algorithm - 最快的连续循环检测
- swift - GCP 应用程序凭据随机停止工作
- css - 关于追踪 ::marker 使用的问题
- excel - Get name of the file from which the button was pressed on the toolbar