获取具有相似声音的记录
Posted
技术标签:
【中文标题】获取具有相似声音的记录【英文标题】:Get records with similar sounds 【发布时间】:2014-04-10 09:56:09 【问题描述】:我想从联系人表中查找名称与声音匹配的所有重复名称。例如:Rita 或 Reeta、Microsoft 或 Microsift、Mukherjee 或 Mukherji。
我使用了以下查询:
SELECT contacts.id
FROM contacts
INNER JOIN (
SELECT first_name, last_name, count(*) AS rows
FROM contacts
WHERE deleted = 0
GROUP BY SOUNDEX(first_name), SOUNDEX(last_name)
HAVING count(rows) > 1
) AS p
WHERE contacts.deleted = 0
AND p.first_name SOUNDS LIKE contacts.first_name
AND p.last_name SOUNDS LIKE contacts.last_name
ORDER BY contacts.date_entered DESC
上面的查询给出了正确的结果,但是当有很多记录时会花费很多时间。
【问题讨论】:
它会的。您的问题无法快速解决,因为“听起来很相似”的事情无法快速解决。因此,SOUNDEX
很慢,整个查询也很慢
除了使用跑得更快的SOUNDEX,还有其他方法吗?
确定哪些字符串“听起来相似”?不,但如果你可以简化“听起来很相似”这个词 - 可能是
【参考方案1】:
我不知道有比SOUNDEX()
更好的(本地)方法。它缓慢的原因是因为它是一个函数,因此需要处理所有记录以计算值并从那里开始工作。解决此问题的一种方法是将结果直接存储到表中。我在 mysql 中没有使用这些函数的经验,但根据documentation,您似乎可以将WHERE
子句转换为
[...] AND SOUNDEX(p.first_name) = SOUNDEX(contacts.first_name) [...]
因此,如果您已经预先计算(并编制了索引!)这些值,那么搜索匹配记录的速度应该会快得多!
也就是说,我很难弄清楚您的问题。我认为您不需要那里的HAVING COUNT(*) > 1
,即使那样我也对您要如何对联系人进行分组/过滤感到困惑!?
你想要这样的东西吗:
SELECT c1.id as contact_id,
c2.id as similar_id
FROM contacts c1
JOIN contacts c2
ON c2.id <> c1.id
AND c2.deleted = 0
AND SOUNDEX(c2.first_name) = SOUNDEX(c1.first_name)
AND SOUNDEX(c2.last_name) = SOUNDEX(c1.last_name)
WHERE c1.deleted = 0
ORDER BY c1.date_entered DESC
然后您可以按照上面的建议进行优化
SELECT c1.id as contact_id,
c2.id as similar_id
FROM contacts c1
JOIN contacts c2
ON c2.id <> c1.id
AND c2.deleted = 0
AND c2.first_name_soundex = c1.first_name_soundex
AND c2.last_name_soundex = c1.last_name_soundex
WHERE c1.deleted = 0
ORDER BY c1.date_entered DESC
其中 first_name_soundex 保存 SOUNDEX(first_name) 等的结果。
编制索引时,您可能希望在deleted
、first_name_soundex
、last_name_soundex
上有一个覆盖索引。
(AFAIK MySQL 还不支持过滤索引,否则您可以将索引限制为仅deleted = 0
)。
【讨论】:
【参考方案2】:SOUNDEX(恕我直言)的效用非常有限。一个极端的例子……
SELECT SOUNDEX('cholmondley');
+------------------------+
| SOUNDEX('cholmondley') |
+------------------------+
| C4534 |
+------------------------+
SELECT SOUNDEX('chumleigh');
+----------------------+
| SOUNDEX('chumleigh') |
+----------------------+
| C542 |
+----------------------+
【讨论】:
以上是关于获取具有相似声音的记录的主要内容,如果未能解决你的问题,请参考以下文章