【问题标题】:Can INSTR() in MySQL benefit from an index?MySQL 中的 INSTR() 可以从索引中受益吗?
【发布时间】:2020-10-09 09:54:30
【问题描述】:

我有一个看起来像这样的用户表用于测试:

USER
----------------------------------
id   username           name
1    "djangoIsAwesome"  "Ale"
2    "craze123"         "John"
3    "hope this works"  "JJ"
4    "Rage"             "Ludo"
5    "coolguy1996"      "Frank"

我需要执行非常高效的查询,以便在有人输入用户搜索时做出响应。通常人们会使用 LIKE %string% 策略,但我不能在这里使用,因为 USER 表有数百万行。

我在 (username, name) 上创建了全文索引,但似乎全文索引不支持 substring 查询。

看来我最后的手段是使用 INSTR()。任何类型的列索引都会使 INSTR() 函数受益吗?

查询示例:

“J”、“wesome”、“96”、“k”

【问题讨论】:

  • "J", "96", "k" - 太短(参见innodb_ft_min_token_size 变量)。 “wesome”全文不搜索子字符串。
  • @Akina 除了 LIKE %string% 之外,MySQL 中是否还有其他功能可以搜索子字符串?
  • INSTR() 和 LOCATE() 函数。
  • @Akina 任何组合列索引是否有利于 INSTR 或 LOCATE 查询?
  • 没有索引可以改善子字符串搜索。除了严格从值的开头搜索。

标签: mysql sql django database-design full-text-search


【解决方案1】:

函数和运算符的使用几乎总是排除索引的使用。 INSTR() 绝对属于这一类。 LIKE 具有常量模式且模式开头没有通配符是一个例外。

如果您需要处理此类情况,您可以研究其他具有更广泛索引功能的数据库(尤其是 Postgres)——包括有助于部分字符串匹配的索引。

您还可以使用 n-gram 在 MySQL 中实现类似的功能。但是,这需要单独的数据结构和一些复杂性。

您也可以使用全文索引来实现这一点——但要在输入中修改数据。例如,您可以提取相邻的三个字母组合并将它们添加到索引中,因此:

'Frank' --> 'Frank Fra ran ank'

【讨论】:

  • 有趣的解决方案,我试试看。
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 2011-10-14
  • 1970-01-01
  • 2013-07-20
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
相关资源
最近更新 更多