如何加快MySQL中多个字段的LIKE%foo%搜索速度

时间:2015-03-24 19:58:26

标签: mysql database database-design

我正在寻找一种方法,在MySQL数据库中的两个表中进行快速尽可能不完整的单词LIKE "%foo%"查找。

假设我有两个表,Boxes和Objects,其中每个Box包含多个对象。我们想要做的是通过将搜索字符串与Box.nameObject.name匹配来查找框的ID(Box.id)。

为了给你一张我们正在处理的音阶图片,Boxes包含~500,000个条目,而Objects包含约200,000个条目。

每个对象都在一个Box中,而不是每个Box都包含对象。我有Box.idObject.idObject.box_id的索引。

为什么吗

我需要快速(200ms)这样的数据,所以当用户输入搜索时我可以提供建议。数据集基本上是静态的,每年更新一次。 Box.id永远不会改变。我正在使用初始通配符,因为匹配的单词可能不会从字符串的开头开始 - 例如,"flo"需要建议"cake flour"以及"flour"

我尝试了什么:

在两个表之间进行LEFT JOIN:

SELECT b.id, b.name, o.name FROM boxes b LEFT JOIN objects o ON (b.id = o.box_id) WHERE ((b.name LIKE "%test str%") OR (o.name LIKE "%test str%")) LIMIT 10;

搜索时间:3900ms.

将所有内容归一化为一个查找表:

SELECT n.id, n.box_name, n.object_name from lookup_table n WHERE ((n.box_name LIKE "%test str%") OR (n.object_name LIKE "%test str%")) LIMIT 10;

搜索时间:1100ms

摆脱那种加入显然有奇迹;但是,这仍然太慢了。理想情况下,这应该需要200毫秒或更短。有没有人对如何优化部分字匹配查询有任何见解?

2 个答案:

答案 0 :(得分:2)

查看全文索引。你不应该使用通配符作为生产系统中的第一个字符进行查询。

不要非规范化,因为存在与此相关的其他问题,包括特殊的数据完整性问题,表格过宽导致的其他性能问题,当一对一关系变为一对多时出现问题,其他受影响的代码将会出现问题休息等。加入很好。你应该想要连接,像连接这样的数据库。当然,您应该确保您加入的字段已编入索引。

答案 1 :(得分:0)

如果这是UI中的JS应用程序,请查找执行所需操作的程序包。它们的调整速度很快,并且不依赖于SQL。