MySQL не использует индексы.

DavyJohnes
На сайте с 05.01.2011
Offline
84
2952

Запрос:

SELECT * FROM test_table ORDER BY num DESC LIMIT 123,23

В таблицу ~700k строк.

Имеется индекс по толбцу 'num'.

Играясь со значениями параметром LIMIT, обнаружил что если задать LIMIT 100000,20 то Mysql не использует индекс для этого запроса, в следствии чего запрос получается очень долгим.

Объясните, пожалуйста, почему так происходит?

https://handy-tools.io (https://handy-tools.io) - Набор полезных утилит для всех!
LEOnidUKG
На сайте с 25.11.2006
Offline
1774
#1

А мускуль то какой версии?

✅ Мой Телеграм канал по SEO, оптимизации сайтов и серверов: https://t.me/leonidukgLIVE ✅ Качественное и рабочее размещение SEO статей СНГ и Бурж: https://getmanylinks.ru/ ✅ Настройка и оптимизация серверов https://getmanyspeed.ru/
natural born killer
На сайте с 06.10.2007
Offline
74
#2

Есть дока по мускуль 5 вот тут http://mysql.ru/docs/man/MySQL_indexes.html

Там внизу написано, может подойти под ситуацию:

В некоторых случаях MySQL не использует индекс, даже если это возможно. Несколько примеров таких ситуаций приведено ниже:

- Если использование индекса требует от MySQL прохода более чем по 30% строк в данной таблице (в таких случаях просмотр таблицы, по всей видимости, окажется намного быстрее, так как потребуется выполнить меньше операций поиска). Следует учитывать, что если подобный запрос использует LIMIT по отношению только к извлекаемой части строк, то MySQL будет применять индекс в любом случае, так как небольшое количество строк можно найти намного быстрее, чтобы вернуть результат.
- Если диапазон изменения индекса может содержать величины NULL при использовании выражений ORDER BY ... DESC.
Блог Белого Негра (http://niggaslife.ru)
DavyJohnes
На сайте с 05.01.2011
Offline
84
#3
LEOnidUKG:
А мускуль то какой версии?

5

natural born killer:
Есть дока по мускуль 5 вот тут http://mysql.ru/docs/man/MySQL_indexes.html

Там внизу написано, может подойти под ситуацию:

Не, ни то ни другое не походит.

[umka]
На сайте с 25.05.2008
Offline
456
#4
DavyJohnes:
в следствии чего запрос получается очень долгим.

Потому что индекс используется только для сортировки, а для выборки 20 строк, начиная со 100000-й, ему нужно перелопатить эти 100000 строк.

В данном случае можно либо добавить колонку, записать в неё номера строк по порядку, проиндексировать и делать выборку с помощью WHERE row_id>=100000 AND row_id<100020, либо кэшировать результат.

Лог в помощь!
DV
На сайте с 01.05.2010
Offline
644
#5

А двиг-то какой у MySQL? И 5-х версий много...

VDS хостинг ( http://clck.ru/0u97l ) Нет нерешаемых задач ( https://searchengines.guru/ru/forum/806725 ) | Перенос сайтов на Drupal 7 с любых CMS. ( https://searchengines.guru/ru/forum/531842/page6#comment_10504844 )
N
На сайте с 06.05.2007
Offline
419
#6

Покажи результат EXPLAIN, SHOW CREATE TABLE, а потом уже будут конкретные советы.

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

Кнопка вызова админа ()
DavyJohnes
На сайте с 05.01.2011
Offline
84
#7
DenisVS:
А двиг-то какой у MySQL? И 5-х версий много...

InnoDB

netwind:
Покажи результат EXPLAIN, SHOW CREATE TABLE, а потом уже будут конкретные советы.
Для совсем уж конкретных советов, лучше выложить дамп тестовых данных и запросов, где проблема воспроизводится.


EXPLAIN SELECT * FROM log_search ORDER BY COUNT DESC LIMIT 1000,10

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE log_search index IND_COUNT 2 1010


EXPLAIN SELECT * FROM log_search ORDER BY COUNT DESC LIMIT 100000,10

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE log_search ALL 749426 Using filesort

CREATE TABLE `log_search` (
`id` mediumint(6) unsigned NOT NULL AUTO_INCREMENT,
`name` tinytext NOT NULL,
`count` smallint(7) unsigned NOT NULL,
`type` tinyint(1) unsigned NOT NULL,
`sm` tinyint(1) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `ft_name` (`name`(40)),
KEY `IND_COUNT` (`count`)
) ENGINE=InnoDB AUTO_INCREMENT=804264 DEFAULT CHARSET=cp1251
N
На сайте с 06.05.2007
Offline
419
#8

Можешь попробовать поиграть в USE INDEX/FORCE INDEX, но не обязательно это ускорит запрос.

Скорее всего распределение по этому индексу неравномерное. Например в конце, если двигаться по порядку count DESC ( и зачем называть поля зарезервированным словом COUNT ?), много одинаковых значений count.

Одними индексами и запросами тут ничего не сделать. Нужно пересмотреть условия задачи. Например, добавить еще одно поле - порядок. Там уже зависит от предметной области. И вообще кому и зачем понадобилось листать до 100000-ой записи, если они там все одинаковые по полю count ?

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий