我一直在使用MySQL上的索引(5.5.24,WinXP),但是我找不到使用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 DOES使用索引。
那么,我在这里看不到什么?问题在哪里?
感谢您的帮助。
答案 0 :(得分:8)
如果索引导致访问超过30%的表行,则MySql可以忽略索引。 您可以尝试FORCE INDEX [index_name],它会在任何情况下都使用索引。
sysvar_max_seeks_for_key的值也会影响是否使用索引:
http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#sysvar_max_seeks_for_key
尝试将此值更改为较小的数字。
在SO上搜索类似的请求。
答案 1 :(得分:1)
基于Ubik comment和数据更改,我发现: 在这些情况下使用的索引 IS :
- 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';
但当我使用此查询时,索引 NOT :
- explain select * from testTable force index jeje where startDate like 'aaaaaaaaa';
基于 startDate 列中所有值具有相同长度(9个字符)的事实,当我使用LIKE命令和9个字符常量使用查询时, PERHAPS < / b> MySQL更喜欢不使用原因,因为有一些性能算法,并转到表中。
我担心的是看我是否在原始测试中犯了某种错误,但现在我认为索引和测试是正确的,并且MySQL在某些情况下决定不使用索引......而我将转发此事。
对我来说,这是一项封闭的任务。 如果有人想在线程中添加一些东西,欢迎你。