#mysql #запрос #index
Добрый день, есть вот такая таблица: CREATE TABLE IF NOT EXISTS `ip_city` ( `ip_from` int(10) unsigned NOT NULL, `ip_to` int(10) unsigned NOT NULL, `locid` int(10) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; Индексы: ip_from BTREE ip_from ip_to BTREE ip_to ip_from_2 BTREE ip_from, ip_to И запрос: SELECT * FROM `ip_city` WHERE (`ip_from` < 2995257412) AND (`ip_to` > 2995257412) Никак не могу добиться вменяемого результата, никакой индекс не цепляет.
Ответы
Ответ 1
Выборки из одной таблицы Возьмем таблицу пользователей с набором личной информации, проиндексированную по адресу электронной почты. Вот пара простых условий, которые могут получить преимущества от индексов: EmailAddress = 'vasya.pupkin@mail.ru' написал равно вместо LIKE так как сам удивился результатам EXPLAIN'а, нужны дополнительные исследования - точно определенное значение всегда имеет возможность использовать индекс, сервер пройдется по дереву и получит точное указание на запись или несколько записей в таблице. Сразу нужно отметить, что, определяя колонку уникальной, автоматически создается индекс по ней. Зачем? Иначе было бы накладно перед каждой вставкой или изменением в таблице проверять все значения поля на соответствие условию уникальности, а так можно быстро проверить существование записи. EmailAddress LIKE 'vacya.pupkin@%' - частичное использование индекса. Повторю, что должна быть определена крайняя левая часть и только она может быть использована для поиска по индексам. Например, для условия EmailAddress LIKE 'vasya.%@mail.ru' тоже будет использован индекс, но в поиске в структуре индекса будет участвовать только vasya., а остальная часть будет проверена последовательным сканированием строк, найденных с помощью индекса. К этому примеру мы вернемся при рассмотрении особенностей составных индексов. Те же условия распространяются на операции с числами: равенство, больше, меньше и другие. Нетрудно догадаться, что некоторые условия можно привести к альтернативным выражениям с использованием элементарных операций, например, BETWEEN, который тоже оптимизируется. (ссылка на источник) В таком случае вы можете попробовать использовать директиву USE INDEX или FORCE INDEX. UPD В качестве оптимизации также можете попробовать в запросе вместо выборки всех полей, "*", перечислить только те поля, которые вам действительно нужны. Это сократит количество выбираемых и пересылаемых данных.Ответ 2
Оптимизатор начинает использовать индексы только если по его предварительной оценке, количество записей в результате будет не более 30% от общего количества записей в таблице. Иначе, он абсолютно справедливо считает, что быстрее будет тупо перелопатить все записи таблицы не используя индексы. Индекс не будет использован, если использование индекса требует от MySQL прохода более чем по 30% строк в данной таблице (в таких случаях просмотр таблицы, по всей видимости, окажется намного быстрее, так как потребуется выполнить меньше операций поиска). Поэтому ставьте хоть FORCE INDEX или USE INDEX - быстрее не станет.
Комментариев нет:
Отправить комментарий