在innoDB中优化MySQL LIKE'%string%'查询

时间:2012-04-27 16:17:06

标签: mysql sql indexing query-optimization

有这个表:

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'无论%',那么这个索引表现良好,但在其他方面没有价值。

无论如何都要为innoDB优化这个吗?

谢谢!

2 个答案:

答案 0 :(得分:43)

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

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

这就是为什么你使用全文索引,如果你所做的只是“浮动”搜索,因为它们是为这种用法而设计的。

主要说明:InnoDB现在是supports fulltext索引,版本为5.6.4。所以除非你不能升级到至少5.6.4,否则没有什么能阻止你使用InnoDB * AND 全文搜索。

答案 1 :(得分:0)

我想评论一下,令人惊讶的是,在我的案例中,创建索引也有助于加快like '%abc%'查询的查询速度。

MySQL 5.5.50上运行Ubuntu(将所有内容保留为默认值),我创建了一个包含大量列并插入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必须搜索所有行,但仍然可以使用索引?