[MySQL, solved] Почему-то не используется индекс

doublemother

mysql> show create table myTable \G
*************************** 1. row ***************************
Table: myTable
Create Table: CREATE TABLE `myTable` (
`id` int(11) NOT NULL auto_increment,
`ionic` text,
`weight` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=15829 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Когда делаю селект:
mysql> explain select id,ionic from myTable where id>100\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: myTable
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 8070
Extra: Using where
1 row in set (0.00 sec)

Если явно указать USE KEY (PRIMARY ключ всё равно не используется. Попробовал создать индекс по полю weight и в where вместо id наложить условие weight>0 - ключ всё равно не используется. Но почему-то соглашается использовать ключ, если выбираю только одно поле id, без поля ionic.
Кто-нибудь знает, почему так может происходить? Версия мускуля 5.0.51a-3 (Debian).

katrin2201

Не скажу, как конкретно в мускуле, но обычно такое возникает, когда CBO по каким-то причинам решает, что прочитать всю таблицу проще

6248874

Если у тебя в таблице около 8к записей, то в результат по твоему условию попадут почти все. Индекс же дает существенный прирост производительности, когда мы выбираем не более 10% от всех записей. Логично, что СУБД решает не использовать его, а использовать sequential scan - это быстрее
По поводу вот этого
 
Но почему-то соглашается использовать ключ, если выбираю только одно поле id, без поля ionic.

При выборке только id их можно целиком выбрать по индексу, не прибегая к чтению самих записей с диска

ermsoft

USE KEY (PRIMARY) - это всего лишь рекомендация.
Чтобы форсировать использование, надо писать FORCE KEY (PRIMARY).
Если с ключом правда лучше, то можно попробовать еще analyze table, оно пересчитает распределение ключей в индексе, и оптимизатор запросов может изменить свое мнение о том, надо использовать индекс или нет.
Впрочем, если в базе 15829 строк, и хочется выбрать из них все, кроме первых 100, то mysql прав, в таком запросе индекс только помешает.

doublemother

Оказалось, действительно анализатор мускуля сбрендил. Изначальная проблема возникла собственно из-за неиспользования мускулем индекса при джоине таблицы самой с собой по индексированному полю. Optimize table и repair table пробовал, а про analyze table забыл. Именно он и помог :)
Оставить комментарий
Имя или ник:
Комментарий: