【问题标题】:MySQL - LIKE with trailing wildcard vs range searchMySQL - LIKE 与尾随通配符与范围搜索
【发布时间】:2026-01-22 13:05:01
【问题描述】:

我想找到更好的方法,主要是我的数据库中的性能问题。通配符 LIKE,还是范围搜索?

让我们有这张桌子:

| id INT | created DATE | some other columns ... |

如果我想选择某个月份创建的条目,我可以考虑两个选项。一个是在一个范围内搜索的一对比较:

SELECT * FROM my_table WHERE created >= '2014-09-01' AND created < '2014-10-1'

第二个是通配符LIKE:

... WHERE created LIKE '2014-09-%'

我创建了一个包含数百个条目的虚拟表,分为三个月。当我在两种条件下运行选择时(禁用缓存和在列上创建索引),时间大致相同 - 第一个更快,第二个更快。在旧的 Atom CPU 上,时间在 4.0 到 5.0 毫秒之间。

在我看来,从性能的角度来看,我将使用哪一个并不重要。这是正确的吗?还是会有数千行出现差异?

谢谢

【问题讨论】:

  • @Giles 将列 created 包装在函数中将导致索引不可用。
  • 使用 YEAR() 和 MONTH() 只需要我两个选项的一半时间。所以这似乎是迄今为止最好的选择。 :-)
  • 您需要更多行。 @Giles,不过我不会提出比之前的建议更糟糕的替代方案,即范围扫描。
  • 我会多看一下日期相关的功能和操作,然后用更多的行来测试它。几万就够了?谢谢大家的回答。
  • 我已经在我的系统上测试了这两种方法(大约 700 万行),它们都可以使用索引。

标签: mysql sql wildcard date-range


【解决方案1】:

通配符前缀几乎使优化器无法使用索引,我猜想执行范围查询(尤其是在日期 types 上)总是比字符串比较好。

加上几百行并不能说明这一点:数据缓存的差异、其他进程使用的 CPU 将超过毫秒的差异。

编辑:但重申一下,这里主要是比较日期和日期,而不是日期和字符串。这会在某个阶段回来咬你。

例如

where created >= STR_TO_DATE('2014-09-01','%Y-%m-%d') 
  and created < STR_TO_DATE('2014-10-01','%Y-%m-%d')

【讨论】:

  • @Giles:如果该列实际上是日期类型,则不是:那么可以使用索引扫描。
  • @Giles,不会的。我认为前缀 % 和第二个后缀 % 是问题中的拼写错误。
  • @Arth:是的,我在问题中解决了它。我真的只使用后缀通配符。复制和粘贴错误。
  • @Giles:该索引可能不会用于其他原因,例如表足够小,可以进行表扫描。
  • @Arth:好的,会的:)
【解决方案2】:

在我的系统(约 700 万行)上进行了测试,这两种方法都可以使用索引,差异可以忽略不计。

但是,我的建议是;使用日期范围。从表面上看更有意义。

此外,您可能会在其他地方使用范围进行数据过滤,而这实际上无法使用 LIKE 完成。例如created &gt;= CURDATE() - INTERVAL 2 DAY

使用范围将使您的代码保持一致。

顺便说一句,我可能会将您的查询更改为:

SELECT * FROM my_table WHERE created >= '2014-09' AND created < '2014-10'

为了表明这一天没有被使用。

【讨论】: