【问题标题】:How to use index for VARCHAR field in MySQL with LIKE and partial match?如何在 MySQL 中使用 LIKE 和部分匹配的 VARCHAR 字段的索引?
【发布时间】: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%' 使用索引。查看内置的全文搜索。

标签: mysql sql database indexing database-indexes


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-06
    • 2011-08-10
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2012-05-31
    相关资源
    最近更新 更多