在LIKE上没有用于INT的MySQL索引?

时间:2017-07-26 15:13:24

标签: mysql sql select indexing

我不知道这是一个错误或功能,还是我做错了什么。我继承了一个有几十万行的MySQL数据库。此表格包含字段" full_name'这是一个VARCHAR,' workpack'这是一个INT。

此表的一个用途是在人们开始填写HTML表单时提供自动完成功能,这在上述字段中提供。我注意到在输入' full_name'自动填充功能会出现并快速更新,但在键入' workpack'自动完成显示和更新很慢,几乎无法使用。

这两个字段都被编入索引,查询结构的简化示例如下:

SELECT distinct full_name       
FROM xx.xx
WHERE full_name LIKE 'Joe Bl%';

EXPLAIN建议使用索引' full_name'如预期的那样。

' workpack'几乎完全相同的查询:

SELECT distinct workpack
FROM xx.xx
WHERE workpack LIKE '153%';

这里的EXPLAIN显示它没有使用索引' workpack',即使我使用FORCE INDEX。

因为我能看到的唯一区别是一个是INT而另一个是VARCHAR,我决定通过创建表的本地副本并更改' workpack'的数据类型来进行实验。到VARCHAR。有效!对某些人来说也许并不令人惊讶,但我想知道为什么会这样。显然我的工作包'数据应该存储为INT,因为它是什么,但是为了使我的自动完成功能以合理的方式工作,我似乎需要将其更改为VARCHAR。我意识到LIKE是一个字符串函数,但由于LIKE函数仍然适用于INT,它是否因为它是INT而无法使用索引的逻辑上的技术原因?

2 个答案:

答案 0 :(得分:2)

索引在这里不合适,因为您将其转换为字符串。如果您使用其值或字符串表示形式对数字列表进行排序,结果将会有所不同。以示例125和1234为例。按值排序时,您会得到:

  • 125
  • 1234

按字符串表示法排序时,你会得到:

  • 1234
  • 125

所以索引在你的情况下没用,因为它是在值的顺序(因为你的字段是一个int),而你的搜索需要字符串顺序(因为你使用like来找到一些字符串前缀) 。 (请记住,索引实际上只是一个排序列表)

答案 1 :(得分:1)

索引本质上是一种排序数据结构,它从列的映射到包含它的行。因此,它只能在您的查询使用实际值时使用,而不是对其进行某些转换(例如将Warning messages: 1: running command 'C:\Program Files\mingw-w64\x86_64-5.3.0-posix-seh-rt_v4-rev0\mingw64\bin /c PATH' had status 127 2: In shell("PATH") : 'PATH' execution failed with error code 127 转换为int)。

针对此类问题的一个简洁解决方案(自MySQL 5.7.6起可用)是添加自动生成的列,仅用于索引并在此类查询中使用它。它可能会浪费一些空间(因为您拥有相同数据的两个副本 - 原始数据和计算列),但如果您的应用程序大量使用此查询,则可能值得:

varchar