【问题标题】:MySQL full text search matching similar resultsMySQL全文搜索匹配相似结果
【发布时间】:2014-09-21 10:10:30
【问题描述】:

我将尝试解释我的情况:我正在尝试为我的网站上的产品创建搜索引擎,因此当用户需要查找产品时,我需要显示类似的产品,这里有一个示例。

用户搜索:
assassins creed OR assassinscreed OR aSsAssIn's CreeD 假设没有字母/数字拼写错误(这 3 个查询应该产生相同的结果)

预期结果:
Assassin's Creed AND Assassin's Creed: Unity AND Assassin's Creed: Special Edition

到目前为止我尝试了什么

  • 我为搜索引擎创建了一个 MySQL 字段,其中包含已解析的产品名称 (Assassin's Creed: Unity -> assassinscreedunity
  • 我解析搜索查询
  • 我使用 MySQL 的 INSTR() 进行搜索

我的问题

我用这个没问题,但我听说行数增加时它会变慢,我在我的表中创建了一个全文索引,但我认为它没有帮助,所以我需要另一种解决方案。
感谢您的任何回答,并在投票前问我任何问题。

【问题讨论】:

  • 您是遇到性能问题还是只是“听说它可能很慢”?
  • @andy 我在某处读过,它与LIKE 相同,它在不使用和索引的情况下遍历所有记录,所以我认为当行数增加时它会减慢很多。
  • 您希望有多少行?如果你只有几百个游戏名称的表格,你不必担心。
  • @andy 更多,所以查看所有记录不是我的解决方案

标签: mysql search search-engine


【解决方案1】:

首先,您应该更准确地跟踪查询中的性能问题,而不是“听说它可能很慢”和“认为它会有所帮助”。一个起点可能是Slow Query Log

如果您的表在多行中包含相同的解析名称,请考虑 normalizing 您的数据库。在特定情况下,将唯一的解析名称存储在一个表中,并且仅将相应解析名称的 id 存储在您在问题中描述的表中。这样,您只需要检查具有唯一名称的较小表,然后可以通过id快速找到主表中所有匹配的条目。

示例:

根据您的结构考虑下表

 id | product_name        | rating
-----------------------------------
 1  | assassinscreedunity | 5
 2  | assassinscreedunity | 2
 3  | monkeyisland        | 3
 4  | monkeyisland        | 5
 5  | assassinscreedunity | 4
 6  | monkeyisland        | 4

您必须扫描所有六个条目才能找到相关行。

相比之下,考虑两个这样的表:

 id | p_id | rating
--------------------
 1  | 1    | 5
 2  | 1    | 2
 3  | 2    | 3
 4  | 2    | 5
 5  | 1    | 4
 6  | 2    | 4

 id | name
--------------------------
 1  | assassinscreedunity
 2  | monkeyisland

在这种情况下,您只需扫描两个条目(与六个相比),然后就可以使用整数 id 有效地查找相关行。

为了进一步提高性能,您可以扩展解析名称的概念并使用哈希。例如,您可以计算已解析名称的 SHA1 哈希值,即 160 位值。您可以非常有效地在数据库中找到该值的条目。要匹配子字符串,您也可以将它们添加到第二个表中。由于哈希只需要计算一次,您仍然可以使用数据库来匹配整数。对你来说另一件事可能是fuzzy hashing

此外,您通常应该阅读Rabin–Karp algorithmstring searching

【讨论】:

  • 这不是查询速度的问题,而是“当我有类似 10000 多行的数据时,我可以使用哪些函数/方法来获得更快的结果(比使用INSTR())一个一个地解析它们?”。具有相同的解析名称不是问题,因为它会在整个表中出现 3/4 次,因此不值得创建单独的表
  • @RomanHudylko 将相同的解析名称减少为单个实例也会将搜索的行数减少 3-4 倍!对于功能部分,我更新了我的答案。
  • 为同名的行创建一个实例是没有意义的,因为同名的行有不同的 id...截至您的更新:我认为我不完全理解它是如何做到的应该可以帮助我。我也需要能够找到类似的值,这就是我使用 INSTR() 的原因,我应该如何使用 SHA1-hash,你能给我举个例子吗?
  • @RomanHudylko 确实有道理。我希望我的最后一次编辑能清楚地说明这一点。
  • @RomanHudylko 首先,您的新解决方案甚至不适用于您的问题中提到的用户输入assassinscreed。其次,我的回答是故意通用的,以适应广泛的问题,包括从你的问题中可以想象到的所有问题。请接受答案或改写您的问题。但是,我建议您接受并提出一个新问题,因为您显然在寻找完全不同的东西。
猜你喜欢
  • 2014-02-18
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2021-09-10
  • 1970-01-01
相关资源
最近更新 更多