为什么整数搜索字符串在字符字段上较慢?

Gif*_*ise 3 mysql

我在我的工作场所使用 MySQL 5.1 版。

my_cloumn char(10)my_table.

我最近发现一个过程需要更长的时间,负责这个的 SQL 如下:

SELECT * FROM my_table WHERE my_column = 12345,这可能需要大约 3 分钟的运行时间。

现在,以这种方式在搜索字符串上编辑和使用引号

SELECT * FROM my_table WHERE my_column = '12345'

在几微秒内检索记录。

我无权(直接或间接)更改代码以通过引号传递查询(通过直接 sql 或在 PDO 中指定正确的数据类型),并且当前可能无法在用户访问时更改列使用数据库。我最需要的是如何解释上述差异。

为什么有引号而不是没有引号会更快?

Low*_*n M 5

引号将表达式定义为字符串,而没有单引号则将其计算为数字。这意味着 MySQL 被迫执行类型转换以将数字转换为 aCHAR以进行适当的比较。

正如上面的文档所说,

对于字符串列与数字的比较,MySQL 无法使用列上的索引来快速查找值。如果 str_col 是索引字符串列,则在执行查找时无法使用该索引...

然而,相反的情况并非如此,虽然可以使用索引,但使用字符串作为值会导致执行计划不佳(如 jkavalik 的sqlfiddle 所示),其中using where使用了而不是更快的using index condition。两者的主要区别在于前者需要行查找,后者可以直接从索引中获取数据。

您绝对应该尽快将列数据类型(假设它确实仅意味着包含数字)修改为适当的数据类型,但请确保没有查询实际上使用单引号,否则您将回到开始的地方。

  • @giftrise 如果您接受用户数据并将其直接放入选择中,那么您遇到的问题比速度要大得多。查找 sql 注入。 (2认同)
  • @JohnM 我发现一个“权威”至少提到了这种区别 - https://www.percona.com/blog/2006/09/08/why-index-could-refuse-to-work/ - 以`开头的段落有趣的是,它以其他方式工作`。 (2认同)