2013-08-13 2 views
0

У меня есть база данных mysql с простой таблицей с именем item. Пункт содержит следующие поля и имеет 55000 записей:MySQL Innodb Полный текст Поиск близости Дает ужасную производительность

ID (PK) Описание (INNODB ПОЛНЫЙ ТЕКСТ) ДАТА

Конструктивно я вынужден индексировать весь путь вплоть до 1 символов слова, поскольку некоторые описания содержат имена, такие как Пункт 1 a 2 42, где пробелы ДОЛЖНЫ быть сохранены. Я бегу полнотекстового поиска против этой таблицы и вот мои результаты следующего кода:

Select ID, Description, Date 
From Item 
WHERE date > DATE_SUB(NOW(), INTERVAL 15 MONTH) 
AND description LIKE CONCAT('%item 1 2 a 4%') 
AND MATCH (description) AGAINST ('+item +1 +2 +a +4' in boolean mode); 

Этот запрос возвращает в 1.2 секунды. Однако, как только я добавить следующий поиск близости к запросу моего возвращения время проходит через крышу:

Select ID, Description, Date 
From Item 
WHERE date > DATE_SUB(NOW(), INTERVAL 15 MONTH) 
AND description LIKE ('%item%') 
AND MATCH (description) AGAINST ('+item +1 +2 +a +4' in boolean mode) 
AND MATCH (description) AGAINST ('"1 2 a 4" @30' in boolean mode); 

Этот запрос возвращает в 54 секунд! Поиск по близости является обязательным для моего запроса, так как мне нужно убедиться, что я нахожу «item 1 2 a», а не «item 1 2 48884848 222 a», который был бы совершенно другим. Поиск близости работает намного лучше, если слова имеют более 1 символа, но есть некоторые обстоятельства, которые потребуют ввода пользователем 1 символьного слова. Есть ли что-то еще, что я могу сделать, это будет альтернативой поиску бесконтактного полнотекстового innodb, но имеет гораздо лучшую производительность? Если в MYSQL нет ничего другого, я открыт для использования чего-то, чтобы интегрироваться, чтобы дать мне лучший поиск по близости (я нахожусь в окнах).

спасибо!

ответ

2

Условие LIKE поражает ваши полнотекстовые индексы. Заменить условие

description LIKE CONCAT('%item 1 2 a 4%') -- and why CONCAT() anyways? 

... с

MATCH (description) AGAINST ('"item 1 2 a 4"' IN BOOLEAN MODE) 

Ваше второе условие бесполезным, так как он совпадает с первым условием (вы уже отфильтрованы по точной строке «пункта 1 2 4», эти строки всегда соответствуют «+ item +1 +2 + a +4»).

+0

Я исправил concat в приведенном выше примере, я передаю некоторые переменные в подпрограмму, поэтому я нашел ее там. Второй пример не заменит поиск близости в моем сценарии. Пользователь мог бы искать «Пункт 125», а описание «Детский синий экстренный широкий 125» по-прежнему нужно было бы сопоставить, но «деталь детализации детали детали детали 25 детали» нужно будет выбросить. У меня странный случай использования. – mscard02

+0

Да, извините за это, я внесла поправки в свой пост, третье условие ** не ** излишне. – RandomSeed

0

Можно ли использовать следующий перезаписанный запрос?

SELECT ID, Description, Date 
FROM Item 
WHERE date > DATE_SUB(NOW(), INTERVAL 15 MONTH) 
AND MATCH (description) AGAINST ('"1 2 a 4" @30 +item' in boolean mode); 

Близость медленно, потому что это сложно. Предложите использовать не более двух слов для поиска близости. По мере увеличения числа слов время запроса увеличивается.