9

我一直在使用 MySQL(5.5.24,WinXP)上的索引,但我找不到在使用 a 时服务器不使用一个索引的原因LIKE

这个例子是这样的:

我创建了一个测试表:

create table testTable (
  id varchar(50) primary key,
  text1 varchar(50) not null,
  startDate varchar(50) not null
) ENGINE = innodb;

然后,我添加了一个索引到startDate. (请不要问为什么该列是文本而不是日期时间。这只是一个简单的测试):

create index jeje on testTable(startdate);
analyze table testTable;

之后,我添加了近 200,000 行,其中startDate有 3 个可能的值。(每一个出现三分之一......接近70,000次)

所以,如果我运行这样的EXPLAIN命令:

explain select * from testTable use index (jeje) where startDate = 'aaaaaaaaa';

答案如下:

id = 1
select_type = SIMPLE
type = ref
possible_keys = jeje
key = jeje
rows = 88412
extra = Using where

因此,使用了密钥,并且行数接近 200,000/3,所以一切正常。

问题是,如果我将查询更改为:(只需将 '=' 更改为 'LIKE'):

explain select * from testTable use index(jeje) where startDate LIKE 'aaaaaaaaa';

在这种情况下,答案是:

id = 1
select_type = SIMPLE
type = ALL
possible_keys = jeje
key = null
rows = 176824
extra = Using where

因此,现在没有使用索引(键为空,并且行接近完整表......正如 type=all 所暗示的那样)。

MySQL 文档说 LIKE 确实使用了索引。

那么,我在这里没有看到什么?哪里有问题?

谢谢你的帮助。

4

2 回答 2

8

如果索引导致访问超过 30% 的表行,MySql 可以忽略索引。您可以尝试 FORCE INDEX [index_name],它无论如何都会使用索引。

sysvar_max_seeks_for_key 的值也会影响索引是否被使用:

在 SO 上搜索类似的请求。

于 2012-08-20T06:30:04.883 回答
1

根据Ubik 评论和数据更改,我发现:在这些情况下使用了索引:

- explain select * from testTable force index jeje where startDate like 'aaaaaaadsfadsfadsfasafsafsasfsadsfa%';
- explain select * from testTable force index jeje where startDate like 'aaaaaaadsfadsfadsfasafsafsasfsadsfa%';
- explain select * from testTable force index jeje where startDate like 'aaa';

但是当我使用这个查询时,索引没有被使用:

- explain select * from testTable force index jeje where startDate like 'aaaaaaaaa';

基于在startDate列中所有值都具有相同长度(9 个字符)的事实,当我使用 LIKE 命令和 9 个字符常量进行查询时, 可能由于某些性能算法, MySQL更喜欢不使用该原因,并且走到桌边。

我担心的是看看我在最初的测试中是否犯了某种错误,但现在我认为索引和测试是正确的,并且 MySQL 在某些情况下决定不使用索引......我会继续这。

对我来说,这是一个封闭的任务。如果有人想在线程中添加一些内容,欢迎您。

于 2012-08-20T14:20:24.237 回答