SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 01.09.2010 12:05:19

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Непонятка с приоритетом индексов

Есть вот такая таблица (упростил до минимума, она на самом деле больше):

CREATE TABLE `nalog_data` (
  `inn` char(12) NOT NULL,
  `namefull` varchar(500) NOT NULL,
  `name` char(255) NOT NULL,
  `namefirm` varchar(255) NOT NULL,
  KEY `inn` (`inn`),
  FULLTEXT KEY `name` (`name`,`namefull`,`namefirm`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251


В таблице примерно 15 миллионов записей

Есть вот такой запрос:

SELECT nlg.inn
FROM
    nlg IGNORE INDEX (`name`)
WHERE 1 = 1
    AND nlg.inn = 'тут число'                    
    AND (
        MATCH (nlg.name,nlg.namefull,nlg.namefirm) AGAINST ('тут некоторый текст' IN BOOLEAN MODE)
    )
 


В столбце inn - почти уникальные значения (~1% дублей)
Explain показывает, что использоваться будет полнотекствый индекс name, почему MySQL отказывается использовать индекс inn??? Причем невзирая на IGNORE/USING/FORCE INDEX. Запрос занимает по разному времени (~25 сек), т.е. счет идет на секунды, хотя если выкинуть условие с MATCH из запроса, то отрабатывает пулей (искомая запись одна, <0,001 сек). Optimize table делал, пофиг. Прям ступор какой то, что я забыл? smile

Отредактированно Shopen (01.09.2010 12:08:06)

Неактивен

 

#2 01.09.2010 12:11:30

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

Наверное,  это все-таки бага MySQL, но такова жизнь. Если он видит специальную
конструкцию MATCH … AGAINST — он всегда предпочитает использовать ее (более
того, она не сработает в случае отсутствия полнотекстового индекса на полях).

В Вашем случае, видимо, прийдется проверять вытащенную строку на клиентской
стороне sad

Неактивен

 

#3 01.09.2010 17:47:59

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Непонятка с приоритетом индексов

Для этого придется сделать свой маленький полнотекствый поиск smile

Неожиданно, мда... Может какие то альтернативы есть? Думал сначала с подзапросом сделать, но к подзапроса MATCH уже не применишь. Остается совершенно феерический вариант делать временную(memory?) таблицу (с индексом name) туда вынимать результат запроса по ключу inn, и в ней уже искать с MATCH ))

Неактивен

 

#4 01.09.2010 18:32:04

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

А, если не секрет, какой там пример запроса внутри? Может, просто комбинация LIKE %word% сработает?
После вытаскивания 1-2 строк должно работать быстро.

Неактивен

 

#5 01.09.2010 20:08:05

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Непонятка с приоритетом индексов

Там произвольная фраза - наименование юридического лица, например "Открытое акционерное общество Вася Пупкин и Ко", так что просто %word% отделаться не получится. Кстати я заметил, что при некоторых inn mysql все таки использует индекс по этому полю. Например если inn="000000000000" или 606060606060 (таких записей не существует), значит все же не всегда. Зависимости пока не уловил.

Неактивен

 

#6 01.09.2010 20:12:31

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

При выборке из таблицы всегда используется максимум один индекс. Чрезвычайно
редко можно добиться INDEX_MERGE — он происходит тогда, когда можно легко
вытащить небольшое количество строк при OR (например WHERE f1 = 1 OR f2 = 2
при существовании индексов на (f1) и (f2) ). Индекс выбирается исходя из оценки
количества полученных строк.

Вы можете написать FORCE INDEX(inn), но, боюсь, что это не поможет, т.к. полно-
текстовый индекс — это таки индекс, и его можно или использовать, или нет. Если
использовать, то (как следует из первого правила) единственным образом. А MATCH()
использует индекс.

Неактивен

 

#7 01.09.2010 20:40:24

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Непонятка с приоритетом индексов

Про FORCE я еще в первом сообщении написал, что не помогает. Мне не нужно добиться одновременного использования индексов. Я не совсем понимаю почему в одних случаях mysql всё-таки использует индекс inn, а в других - нет. Т.е. если бы было как вы сказали в самом начале - что если есть match - то всегда используется fulltext - это было бы плохо, но понятно. Но я наткнулся (совершенно случайно) на то, что все таки при некоторых значениях inn - на MATCH mysql забивает smile
Это при том, что inn практически уникален. Кстати интересно, на уникальный ключ mysql тоже положит?

Отредактированно Shopen (01.09.2010 20:40:59)

Неактивен

 

#8 01.09.2010 21:34:21

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

Можно попробовать поисследовать этот вопрос. У меня ощущение, что он-использует другой индекс только в случае, когда тот выдает заведомо меньше записей (т.е. ноль).

Неактивен

 

#9 03.09.2010 18:35:06

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Непонятка с приоритетом индексов

Очень похоже что так и есть, что еще более странно.

Неактивен

 

#10 03.09.2010 20:29:59

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

Почему странно?

Неактивен

 

#11 03.09.2010 22:05:22

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Непонятка с приоритетом индексов

А как mysql определяет, что таких записей нет при explain, он что индекс просматривает? Ну если он это все равно делает, то обязан знать, что если такой inn существует - то там одна запись, ну две. И тем не менее игнорит этот индекс. Очень странное, имхо, поведение.

UPD. Интересно, если я разнесу эти два поля по разным таблицам и сделаю JOIN - он все равно приоритет матчу будет отдавать? Можно проверить, просто таблица большая, это долго, а может вы заранее знаете, что бесполезно

Отредактированно Shopen (03.09.2010 22:07:28)

Неактивен

 

#12 04.09.2010 11:27:43

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Непонятка с приоритетом индексов

Да, просматривает, и оценивает количество получаемых строк. Но сколько
строк достанется из FULLTEXT он без выполнения запроса не знает. Насколько
я понимаю, нам очень повезло, что там есть дополнительная проверка, что
если строк не вернется вообще. то и запрос выполнять не надо. В альтер-
нативном случае MySQL обязан использовать полнотекстовый индекс, потому
что MATCH он без индекса выполнить не сможет.

Если сделаете JOIN, то получите выборку id по полнотекстовому индексу,
и потом выборку остальных данных по id.

Неактивен

 

Board footer

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