2013-05-21 8 views
0

Так вот сценарий:MySQL - полнотекстовый поиск - Losing индекс

  • MySQL
  • имеют 1 MYISAM Таблица
  • Колум имени v.value имеет полнотекстовый индекс

Основной запрос работает нормально, использует индекс, как ожидалось:

SELECT p.online_identifier 
FROM (...) 
WHERE r.area_id = 3 AND s.state_id= 4 
AND (snap.area_has_catalogues_attributes_id = 7028 
AND MATCH (v.value) AGAINST('+SomeBrand' IN BOOLEAN MODE)) 

Теперь, когда я добавляю OR, индекс полнотекстового поиска (по v.value) не используется. Запустите Explain, чтобы проверить его.

Запрос будет выглядеть примерно так:

(...) WHERE r.area_id = 3 AND s.state_id= 4 AND (snap.area_has_catalogues_attributes_id = 7028 AND MATCH (v.value) AGAINST('+SomeBrand' IN BOOLEAN MODE)) OR (snap.area_has_catalogues_attributes_id = 7045 AND MATCH (v.value) AGAINST('+OtherBrand' IN BOOLEAN MODE))


Я не понимаю, почему. Любые идеи?

ответ

0

Вот что интересно: запрос, который у вас есть, фактически вызывает игнорирование индексации FULLTEXT. Не волнуйся, это не твоя вина. Я писал об этом раньше: Is there a way to hint to query optimizer to MySQL which constraints should be done first?

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

SELECT p.online_identifier 
FROM (...) 
WHERE r.area_id = 3 AND s.state_id= 4 
AND (snap.area_has_catalogues_attributes_id = 7028 
AND MATCH (v.value) AGAINST('+SomeBrand' IN BOOLEAN MODE)) 

Вы должны будете выполнять полнотекстовый поиск в одиночку и получить только идентификаторы.

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


Позвольте мне запрос от одного из my other links, чтобы продемонстрировать, что нужно сделать, чтобы ваш запрос

Вместо этого запроса

select * from seeds WHERE MATCH(text) AGAINST 
("mount cameroon" IN BOOLEAN MODE) = 4; 

вы должны рефакторинга, рефакторинга в нечто вроде этого:

SELECT B.* FROM 
(
    SELECT id,MATCH(text) AGAINST 
    ("mount cameroon" IN BOOLEAN MODE) score 
    FROM seeds 
    WHERE MATCH(text) AGAINST 
    ("mount cameroon" IN BOOLEAN MODE) 
) A 
INNER JOIN seeds B USING (id) 
WHERE A.score = 4; 

Дайте ему попробовать !!!

+0

Прежде всего, большое спасибо за большую помощь. Он направил меня в нужном направлении :) Я пробовал ваш совет, и MySQL использовал индекс :) ​​Результатом было меньше обработанных строк. –

+0

Если вы не возражаете, могу я внести свой вклад в следующий вопрос? [http://stackoverflow.com/questions/16689714/mysql-analyze-query]. Речь идет о производительности запроса, который возник из-за этого :) –

Смежные вопросы