1

这既不是MySQL 索引减慢查询的副本,也不是按索引查询的慢速搜索 LIKE% MYSQL

在一个非常简单的表上,我尝试了一个非常简单的查询,有无特定索引。

表(40 000 行):

id                      int(11)     
shipping_address_id     int(11)     
billing_address_id      int(11)     
label                   varchar(100)
code                    varchar(15) 
email                   varchar(100)

询问 :SELECT email FROM table WHERE email LIKE "%yahoo%"

如果没有“电子邮件”上的索引,则需要 0.0035 秒。然而,有了这个 INDEX,它需要 0.021 秒,慢了 7 倍。

然而,同样的 INDEX 确实将相等查询加速了 50 倍 ( WHERE email = "me@yahoo.com")。

那么,为什么LIKE查询会受到 INDEX 的负面影响?

编辑错字:最初陈述的查询LIKE "yahoo"应该LIKE "%yahoo%"是 ,我很抱歉。

为清晰而编辑:该表是 InnoDB,我正在比较相同查询的速度。在第一种情况下(“LIKE”情况),在比较字段上使用 INDEX 时,查询速度会慢 7 倍。在第二种情况下(“=”),使用 INDEX 的查询速度提高了 50 倍。

4

1 回答 1

1

索引隐式地使用比较运算符解决(并加速)查询:=、<、>。如果你在email字段上有一个索引,并且有一个LIKE查询,MySQL仍然需要检索索引中的所有元素,并将正则表达式应用于它们。

如果查询是

 WHERE email LIKE 'yahoo%com'

您可以通过观察email必须在 'yahoo' 和 'yahoo[' 之间来加快速度(假设 [ 按字典顺序在 z 之后,并且不能出现在该email字段中)。然后将查询更改为

WHERE (email BETWEEN 'yahoo' AND 'yahoo[') AND email LIKE 'yahoo%com'

会产生好处,因为索引会快速预先选择一组较小的行,然后只针对这些行运行正则表达式(在已经可用的字段上,因为它在索引中,所以不需要表查找) .

但在这种情况下,实际上,MySQL 必须进行全表扫描;除了它是在index上这样做的。这样做的成本实际上可能高于“真正的”表扫描。在某些情况下,MySQL 会意识到这一点,并且您会看到该索引实际上根本没有被查询使用(取决于它最近被分析的时间、它的大小和其他因素),并且 MySQL 更喜欢使用完整的索引。表扫描。

索引可能通过收集查询所需的数据来帮助您的另一种情况也不适用,因为您只要求该email字段,这是正在进行的一个计算。因此,该指数再次没有产生任何性能提升。

如果你想要一个加速这种 的索引WHERE,你需要一个FULLTEXT索引,而不是一个“普通”的索引。

于 2013-04-04T15:02:28.453 回答