Ваш запрос почти наверняка связан с повреждением таблицы в MyISAM.
Я сделал
root@localhost [kris]> create table crawler (
id integer not null auto_increment primary key,
provider_id int(11) DEFAULT NULL,
PRIMARY KEY (id),
KEY crawler_provider_id (provider_id)
) engine = myisam;
root@localhost [kris]> insert into crawler ( id, provider_id ) values ( NULL, 1 );</code>
, а затем повторял
root@localhost [kris]> insert into crawler ( id, provider_id)
select NULL, rand() * 120000 from crawler;
, пока у меня не было
root@localhost [kris]> select count(*) from crawler;
+----------+
| count(*) |
+----------+
| 524288 |
+----------+
1 row in set (0.00 sec)
Теперь у меня есть
root@localhost [kris]> SELECT COUNT(*) FROM `crawler` WHERE `crawler`.`provider_id` > 1371;
+----------+
| COUNT(*) |
+----------+
| 518389 |
+----------+
1 row in set (0.27 sec)
, размер которого несколько сравним с тем, что вы дали в своем примере выше.Я получаю два разных плана для запроса с предложением LIMIT и без него.
Без предложения LIMIT я получаю полное сканирование таблицы (ALL) без индекса:
root@localhost [kris]> explain SELECT `crawler`.`id` FROM `crawler` WHERE `crawler`.`provider_id` > 1371\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: crawler
type: ALL
possible_keys: crawler_provider_id
key: NULL
key_len: NULL
ref: NULL
rows: 524288
Extra: Using where
1 row in set (0.00 sec)
Спредложение LIMIT, INDEX используется для доступа RANGE
root@localhost [kris]> explain SELECT `crawler`.`id` FROM `crawler` WHERE `crawler`.`provider_id` > 1371 LIMIT 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: crawler
type: range
possible_keys: crawler_provider_id
key: crawler_provider_id
key_len: 5
ref: NULL
rows: 518136
Extra: Using where
1 row in set (0.00 sec)
В вашем примере, без предложения LIMIT (полное сканирование таблицы) вы не получите данных, но с предложением LIMIT (доступ к диапазону с использованием индекса)Вы получаете данные.Это указывает на поврежденный файл MYD.
ALTER TABLE, например REPAIR TABLE или OPTIMIZE TABLE, обычно копирует данные и сохраненные индексы из исходной таблицы в скрытую новую версию таблицы в новом формате.По завершении скрытая новая таблица заменит старую версию таблицы (которая будет переименована в скрытое имя, а затем отброшена).
То есть, удалив индексы, вы фактически восстановили таблицу.