SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 09.06.2011 09:25:01

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Не работает индекс в запросе

Добрый день. Подскажите пожалуйста почему опримизатор упорно не хочет использовать индекс  в следующем запросе:

SELECT*FROM demands WHERE ping>25;
Вернее он его изпользует судя по explain, поле possible_keys содержит ping, но type все равно показывает ALL, идет полный скан таблицы. Вот сама таблица:
CREATE TABLE demands (id INT NOT NULL AUTO_INCREMENT,symbol CHAR(10) NOT NULL,price DECIMAL(5,2) NOT NULL,amount SMALLINT NOT NULL, user CHAR(10) NOT NULL,ping INT NOT NULL,PRIMARY KEY (id),INDEX ping (ping)) ENGINE=InnoDB;

Неактивен

 

#2 09.06.2011 09:31:29

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Быть может оптимизатор счетает что использовать индекс при выборке того объема данных что находятся в таблице не рентабельно и проще сделать полный скан? Хотя если делать ту же выборку по полю id то все работает как надо.

Неактивен

 

#3 09.06.2011 09:35:10

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Не работает индекс в запросе

Подозреваю, что у Вас количество записей, для которых ping > 25 настолько велико (по сравнению с остальными), что оптимизатор считает, что дешевле сделать FTS.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#4 09.06.2011 10:05:30

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Да нет, записей как раз не много, я сейчас эксперементировал с разным кол-вом записей,100, 1000, 10000 и.т.д эффект тот же, правда колонка rows стала показывать немного меньше кол-во записей затронутых в запросе, но это все равно полный скан. Даже уникальный не помогает.

Неактивен

 

#5 09.06.2011 10:10:53

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Не работает индекс в запросе

А Вы попробуйте обновить статистику индекса запросом analyze table demands.
Сколько у Вас в таблице записей, у которых ping > 25?
Сколько всего записей в таблице?
explain запроса покажите пожалуйста.


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#6 09.06.2011 10:32:30

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Обновил статистику, не помогло. Вот explain на таблицу с 10000 записей: select_type=SIMPLE table=demands type=ALL possible_keys=ping key=NULL key_len=NULL ref=NULL rows=8395 Extra=Using where.

Неактивен

 

#7 09.06.2011 10:35:40

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Не работает индекс в запросе

Ну правильно -  у Вас записей, годящихся под условие 8395 из 10000. Тут куда проще и быстрее сделать FTS, что mysql и делает ). Поменяйте условие например, на "ping < 25", другой explain?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#8 09.06.2011 10:45:40

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Да когда пишу <25 то все работает как надо, rows кажет 24 и type range ,но если пишу скажем >9000 или любое число то rows все равно кажет 8395, ping содержит записй от 1 до 10000 по возрастанию

Неактивен

 

#9 09.06.2011 10:48:19

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Не работает индекс в запросе

Можете приложить структуру и данные таблички сюда (если там нет ничего секретного)?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#10 09.06.2011 11:00:44

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

А если ставлю ping<5000 или > то rows выдает 10445, откуда берутся эти 445 строк? А что за структура таблица? Приложить не могу, так как с КПК пишу в данное время.

Неактивен

 

#11 09.06.2011 11:08:11

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Это вообщем таблица заявок данные хранятся так: id=ид.заявки, symbol=тикер, type=тип заявки(купить,продать) price=цена amount=кол-во user=логин ping=копия ид. Структуру таблицы я описал в 1 посте данного топика, если конечно это структура smile

Неактивен

 

#12 09.06.2011 22:36:45

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Удалил столбцы из таблицы, оставил только столбец id и ping и о чудо индекс наконец заработал как надо. Кошмар какой то. Пробовал добавлять составной индекс опять начинается полный скан. Что за ерунда у меня в компе происходит может кто нибудь объяснить?!

Неактивен

 

#13 09.06.2011 23:21:10

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Не работает индекс в запросе

simple написал:

А если ставлю ping<5000 или > то rows выдает 10445, откуда берутся эти 445 строк? А что за структура таблица? Приложить не могу, так как с КПК пишу в данное время.

Оптимизатор лишь оценивает количество строк, которые вернет запрос. Поэтому число неточное. Если у вас нужно выбрать 8000 из 10000 строк, то лучше перебрать все (чтение диска будет последовательным), чем перескакивать 8000 раз по индексу. Поэтому поведение оптимизатора правильное. id отличается тем, что это первичный ключ - обращение по нему происходит быстрее, чем по вторичному, поэтому решение оптимизатора может быть другим.

Представьте себе, что у вас список 10000 записавшихся на просмотр фильма. Из них нужно исключить 1000 не достигших 18 лет. Вариант с индексом - у вас отдельный список id упорядоченный по возрастам, начинаете с 18 лет, находите соответствующую фамилию в полном списке, выписываете и так последовательно по всем возрастам - при этом нужно переходить от индекса (списка возрастов) к основной таблице по указателю id. Второй вариант - читать основной список и выписывать из него только тех, кому >= 18. Случай бумажного носителя аналогичен жесткому диску - вариант с индексом потребует больше листать (передвигать головку). Если бы данные хранились в памяти, индекс не приводил бы к таким дополнительным затратам.

Неактивен

 

#14 09.06.2011 23:28:50

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Добавил в запрос FORCE INDEX индекс ping наконец то заработал, ура. Но...вкрались сомнения а правильно ли я поступил лишив оптимизатор свободы выбора в выборке, может лучше доверится оптимизатору и оставить все как есть, ведь на то он оптимизатор и ему видней? smile

Неактивен

 

#15 09.06.2011 23:35:50

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

rgbeast, спасиво Вы меня убедили, оставля запрос как есть.

Неактивен

 

#16 10.06.2011 00:10:26

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

А если мне не нужно выберать 8000 записей из 10000 (хотя в исключительной ситуации это может потребоваться), так как условие ping>25 это не константа, по мере заполнения таблицы условия с ping тоже будет увеличиваться, скажем условие ping>9900 для таблицы из 10000 записей, полный скан таблицы тоже будет оправдан?

Неактивен

 

#17 10.06.2011 00:34:24

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Не работает индекс в запросе

Оптимизатор будет решать использовать индекс или нет для конкретного случая (наполненности таблицы и числа 25). Если нет прямого указания, что он ошибается (сравните скорость с FORCE INDEX и c IGNORE INDEX), то ему можно доверять.

Неактивен

 

#18 10.06.2011 00:44:27

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Дело в том что я эксперементировал с разным количеством записей и с разными условиями и все равно идет полный скан. Просто мозгу моему с трудом понимается, как это если скажем таблица достигла размера 50000 записей и нужно выбрать записи где ping >49900, т.е 100 последних записей полный скан будет дешевле.

Отредактированно simple (10.06.2011 00:49:16)

Неактивен

 

#19 10.06.2011 00:49:58

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Не работает индекс в запросе

Например для ping<25 вы писали, что используется индекс. Индекс оправдан обычно только для небольшого количества выбираемых строк. Вопрос имеет смысл, если записей столько, что один из вариантов (FORCE INDEX или IGNORE INDEX) работает существенно медленнее, чем второй. Протестируйте время исполнения на более большой таблице. Тут возможна ошибка оптимизатора, если статистика индексов неточна, но заставить обходить по индексу всю или почти всю таблицу значительно хуже в плане производительности (проверьте)

Неактивен

 

#20 10.06.2011 00:59:04

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

А как сравнить скорость? У меня клиент в обоих случаях выборки 0.000 sec кажет.

Неактивен

 

#21 10.06.2011 01:02:47

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Не работает индекс в запросе

Надо добиться того, чтобы было больше, чем 0.000, иначе сам вопрос теряет смысл. Например, увеличить таблицу в 100 раз. И не забывайте SELECT SQL_NO_CACHE, чтобы из кэша не получать.

Неактивен

 

#22 10.06.2011 01:12:45

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Протестил на таблице с 50000 записей с условием ping>49950 FORCE INDEX показывает время 0.000 sec, IGNORE INDEX  0.063 sec, при условии ping>25000,  0.016 sec (+0.234 sec. Network) и 0.016 sec (+0.172 sec network) соответственно.

Неактивен

 

#23 10.06.2011 01:18:32

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Не работает индекс в запросе

А что выбирает оптимизатор в этих случаях, если сделать OPTIMIZE TABLE;

Неактивен

 

#24 10.06.2011 01:23:04

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

Вобщем мне и не нужно переберать всю таблицу, а нужно только выбирать те записи у которых ping больше прошлого сох.значения ping, это своего рода пеленгатор последних вставленых записей или обновленных. Спасибо, rgbeast, помог разобраться наконец то в этих дебрях smile

Неактивен

 

#25 10.06.2011 01:30:13

simple
Активист
Зарегистрирован: 25.11.2010
Сообщений: 168

Re: Не работает индекс в запросе

После optimize table так же кажет, 0.016 для force 0.063 ignore, так что выбираем force так как мне нужен именно конец таблицы и пусть оптимизатор отдохнет smile

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson