mysql - 在 MySQL 中加速跨多个字段的 LIKE %foo% 搜索的方法

标签 mysql database database-design

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

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

为了让您了解我们正在处理的规模,Boxes 包含约 500,000 个条目,而 Objects 包含约 200,000 个条目。

每个对象都在一个盒子里,并不是每个盒子都包含对象。我在 Box.idObject.idObject.box_id 上有索引。

为什么?

我需要快速(200 毫秒)的数据,以便在用户键入搜索时提供建议。数据集基本上是静态的,每年都会更新一次。 Box.id 永远不会改变。我正在使用初始通配符,因为匹配词可能不会从字符串的开头开始 - 例如,"flo" 也需要建议 "cake 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%")) 限制10;

搜索时间:1100ms

摆脱 JOIN 显然会产生奇迹;然而,这还是太慢了。理想情况下,这应该花费 200 毫秒或更短时间。有没有人对如何优化部分词匹配查询有任何见解?

最佳答案

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

不要非规范化,因为这样做会带来其他问题,特别是数据完整性问题,其他由表太宽引起的性能问题,一对一关系变成一对多时的问题,其他受影响的代码break 等。连接很好。你应该想要连接,像连接这样的数据库。当然,您应该确保您加入的字段已编入索引。

关于mysql - 在 MySQL 中加速跨多个字段的 LIKE %foo% 搜索的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29241744/

相关文章:

mysql - 通过php将csv导入mysql第一行有0

javascript - 将 MySQL 查询转换为等效的 Knex QueryBuilder 语法?

mysql - 存储 URL 的最佳主键

sql-server - 多对多关联表 - 是否习惯在这些表中放置额外的列?

sql - 推荐用于标记或标记的 SQL 数据库设计

mongodb - 按需聚合事件历史记录

mysql - 设置Mysql日期格式

MySQL - GROUP BY 的多个条件及其结果

database - 对分布式事务使用事件溯源是个好主意吗?

c# - 在 mysql 数据库中存储大文件/二进制数据 : when is it ok?