【问题标题】:Optimizing MySQL LIKE '%string%' queries in innoDB在 innoDB 中优化 MySQL LIKE '%string%' 查询
【发布时间】:2012-05-08 09:57:53
【问题描述】:

有这张桌子:

CREATE TABLE `example` (
`id` int(11) unsigned NOT NULL auto_increment,
`keywords` varchar(200) NOT NULL,
PRIMARY KEY  (`id`)
) ENGINE=InnoDB;

我们想优化以下查询:

SELECT id FROM example WHERE keywords LIKE '%whatever%'

该表是 InnoDB,(所以现在没有 FULLTEXT)哪个是优化此类查询的最佳索引?

我们尝试了一个简单的方法:

ALTER TABLE `example` ADD INDEX `idxSearch` (`keywords`);

但是一个解释查询显示需要扫描整个表 如果我们的查询改为 LIKE 'whatever%',则该索引执行良好,否则没有任何价值。

是否有针对 innoDB 进行优化的方法?

谢谢!

【问题讨论】:

标签: mysql sql indexing query-optimization


【解决方案1】:

索引是从字符串的开头到结尾构建的。当您使用LIKE 'whatever%' 类型子句时,MySQL 可以使用那些基于开始的索引非常快速地查找whatever

但切换到LIKE '%whatever%' 会删除字符串开头的锚点。现在不能使用基于开始的索引,因为您的搜索词不再锚定在字符串的开头 - 它在中间某处“浮动”并且必须搜索整个字段。任何LIKE '%... 查询都不能使用索引。

如果您所做的只是“浮动”搜索,这就是您使用全文索引的原因,因为它们是为这种类型的使用而设计的。

主要注意事项:InnoDB 现在supports fulltext 索引自版本 5.6.4 起。因此,除非您无法升级到至少 5.6.4,否则没有什么可以阻止您使用 InnoDB *AND 全文搜索。

【讨论】:

  • 谢谢,我在云环境中使用 MySQL 5.0.77-log,所以无法升级 :( 将考虑将表移至 MyIsam
  • 如果我们迁移到 InnoDB,我们是否需要更改查询以使用 MATCH/AGAINST?或者当前使用“LIKE”会从全文索引中受益吗?再次感谢
  • 不,全文需要匹配/反对的东西。您将不得不重新处理查询。
  • Postgres 为使用 gin 和 pg_trgm 的 %blah% 查询提供了更快的结果。 cybertec-postgresql.com/en/…mysql为什么不能从他们那里得到一些启发?
【解决方案2】:

我想评论一下,在我的例子中,创建索引还有助于加快对 like '%abc%' 查询的查询。

Ubuntu 上运行MySQL 5.5.50(将所有内容保留为默认值),我创建了一个包含很多列的表并插入了100,000 虚拟条目。在其中一列中,我插入了包含 32 个字符的完全随机字符串(即它们都是唯一的)。

我运行了一些查询,然后在该列上添加了一个索引。 一个简单的

select id, searchcolumn from table_x where searchcolumn like '%ABC%'

~2 seconds没有索引和0.05 seconds索引返回结果。

这不符合上面的解释(以及许多其他帖子)。这可能是什么原因?

编辑 我检查了 EXPLAIN 输出。输出显示行是100,000,但额外信息是“Using where; Using index”。所以不知何故,DBMS 必须搜索所有行,但仍然能够利用索引?

【讨论】:

  • 您的查询不包含 LIKE 条件。这就是使用索引的原因。
  • @ditscheri 抱歉,这是一个错字,实际上是 LIKE 条件(刚刚更正了我的帖子)
  • 对于基准测试,您需要在两个查询之间重新启动 mysql。
  • 根据列数、可用 RAM、排序依据、限制等,可能会提高性能,因为引擎能够执行完整索引扫描。这不会像索引查找那样高效,但它可能比全表扫描更有效。
  • @abulhol 这是一个很好的问题,我也很想知道答案。但是,您已发布此问题作为另一个问题的答案。我认为这不是一个好习惯。两个原因: 1. 显而易见 - 如果你知道答案,你应该为 OPs 问题写一个答案。否则,如果您只想讨论与答案相关的内容,请评论其他答案。 2 这个好问题没有得到应有的知名度,因为它没有作为问题发布。 StackOverflow 有自己的系统来提供新问题的可见性,但新答案并没有达到那么远。
猜你喜欢
  • 2013-06-02
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
相关资源
最近更新 更多