如何在 MySQL 中使用 LIKE 和部分匹配的 VARCHAR 字段的索引?

Posted

技术标签:

【中文标题】如何在 MySQL 中使用 LIKE 和部分匹配的 VARCHAR 字段的索引?【英文标题】:How to use index for VARCHAR field in MySQL with LIKE and partial match? 【发布时间】:2014-03-26 14:40:05 【问题描述】:

我有一个 mysql 表,里面有 4200 万条记录。 此表中的“名称”字段有索引(不是唯一且不是 PK)

如果我使用

SELECT x FROM table WHERE name='asdef' 

它使用索引,我很快就得到了结果。

如果我使用

SELECT x FROM table WHERE name LIKE '%sd%'

即使我使用FORCE INDEXUSE INDEX,它也不使用索引。

我绝对需要进行部分匹配。如何在保持字段为 VARCHAR 的同时做到这一点?

【问题讨论】:

在这种情况下数据库会如何处理索引?您的匹配以通配符开头,因此顺序无关紧要。它必须查看匹配的每个名称值。假设“x”不仅仅是“名称”,那么数据库也可能会遍历表行。如果您的匹配模式是恒定的并且您需要经常进行此查找,也许您可​​以在插入时检查此条件并有一个单独的列(例如“has_sd”)和索引,以便您可以快速查找。 @sbaker 我无法检查它,因为name 我无法猜测我搜索的内容,它是由用户动态定义的。 MySQL(与 Postgres 不同)不能为 LIKE '%sd%' 使用索引。查看内置的全文搜索。 【参考方案1】:

嗯,你有问题。而且,SQL 可能会提供一些工具,但它们可能无法解决您的问题。

首先,您的“部分”搜索是否真的是在短语中搜索单词。如果是这样,您可以使用 MySQL 全文搜索来查找单词。您可能需要注意停用词列表和最小搜索长度,以使其适用于您的数据。

其次,名称是否在整个表格中重复?如果是这样,那么标准化将有所帮助。例如,如果 4200 万条记录中有 50000 个名称,则在这 50000 条记录中进行搜索更加可行。

第三,您是否正在寻找一些有限的术语?如果是这样,那么您可以将标志添加到通过触发器维护的表中。

第四,与name 无关的行有多宽?如果行很宽,您可以通过将name 存储在适合并保留在内存中的单独表中来提高穷举搜索的效率。

【讨论】:

以上是关于如何在 MySQL 中使用 LIKE 和部分匹配的 VARCHAR 字段的索引?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL的REGEXP 和 like 在匹配上的区别

MySQL中的Like和正则表达

MYSQL 中的 LIKE 这么用不对?

MySQL中like使用 % 和 _ 的区别

MySQL查询LIKE如何匹配下划线 通配符转义

MySQL - 如何使用 LIKE 搜索精确的单词匹配?