Mysql - выберите, как не использовать индекс

Я играл с индексами в 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

Таким образом, индекс сейчас не используется (ключ равен нулю, а строки близки к полной таблице... как предполагает тип = все).

В документации MySQL говорится, что LIKE использует индексы.

Итак, чего я здесь не вижу? В чем проблема?

Спасибо за вашу помощь.


person Diego Buzzalino    schedule 19.08.2012    source источник


Ответы (2)


MySql может игнорировать индекс, если индекс требует доступа более чем к 30% строк таблицы. Вы можете попробовать FORCE INDEX [имя_индекса], он в любом случае будет использовать индекс.

Значение sysvar_max_seeks_for_key также влияет на то, используется индекс или нет:

Ищите похожие запросы на SO.

person UBIK LOAD PACK    schedule 20.08.2012
comment
Спасибо Убик за ответ. Исходя из этого, я изменил данные таблицы примерно до 300 тыс. строк с 5 возможными значениями в столбце startDate (по 20% каждое). - person Diego Buzzalino; 20.08.2012
comment
Ваш ответ не помог решить проблему, но помог мне мыслить по-разному. Пока у меня нет решения, но есть одно представление о том, что может быть корнем этого. Смотрите мой собственный ответ. Спасибо за помощь!. - person Diego Buzzalino; 21.08.2012

Основываясь на комментарии Ubik и изменениях данных, я обнаружил, что: Индекс 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';

Но индекс НЕ используется, когда я использую этот запрос:

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

Основываясь на том факте, что в столбце startDate все значения имеют одинаковую длину (9 символов), когда я использую запрос с использованием команды LIKE и константы из 9 символов, ВОЗМОЖНО MySQL предпочитает не использовать причину из-за некоторого алгоритма производительности и переходит к таблице.

Меня беспокоило, не делал ли я какую-то ошибку в своих первоначальных тестах, но теперь я думаю, что индекс и тесты верны, и что MySQL в некоторых случаях решает не использовать индекс... и я расскажу об этом. это.

Для меня это закрытая задача. Если кто-то хочет что-то добавить в тему, милости просим.

person Diego Buzzalino    schedule 20.08.2012