Я не понимаю этого.
У меня есть таблица с этими индексами
PRIMARY post_id
INDEX topic_id
FULLTEXT post_text
Таблица имеет (только) 346 000 строк. Я пытаюсь выполнить 2 запроса.
SELECT post_id
FROM phpbb_posts
WHERE topic_id = 144017
AND post_id != 155352
AND MATCH(post_text) AGAINST('http://rapidshare.com/files/5494794/photo.rar')
занимает 4,05 секунды
SELECT post_id
FROM phpbb_posts
WHERE topic_id=144017
AND post_id != 155352
AND post_text LIKE ('%http://rapidshare.com/files/5494794/photo.rar%')
занимает 0,027 секунды.
EXPLAIN показывает, что единственная разница заключается в возможном fulltext
ключе (включая post_text, LIKE
нет)
Это действительно странно.
Что за этим стоит? Что происходит на заднем плане? Как может LIKE
быть так быстро, когда не используется индекс, а FULLTEXT так медленно, когда используется его индекс?
Update1:
На самом деле теперь это занимает около 0,5 секунд, может быть, таблица была заблокирована, но, тем не менее, когда я включаю профилирование, это показывает, что ИНИЦИАЛИЗАЦИЯ FULLTEXT заняла 0,2 секунды. Что происходит?
Я могу запросить мою таблицу с LIKE
10x в секунду, с полным текстом только 2x
UPDATE2:
Сюрприз!
mysql> SELECT post_id FROM phpbb_posts WHERE post_id != 2 AND topic_id = 6 AND MATCH(post_text) AGAINST ('rapidshare.com');
Empty set (0.04 sec)
поэтому я спрашиваю, как это возможно?
Дополнительно,
SELECT count(*) FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com')
действительно медленно. Может быть полный текст какой-нибудь сломан?
Update3:
Что за черт?
SELECT forum_id, post_id, topic_id, post_text FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com') LIMIT 0, 30;
занимает 0,27 с в то время как
SELECT count(*) FROM phpbb_posts WHERE MATCH(post_text) AGAINST ('rapidshare.com') LIMIT 0, 30;
занимает больше 30 секунд! Что здесь не так?
источник
Ответы:
Я думаю, что проблема может быть связана с наличием самого индекса FULLTEXT.
Каждый раз, когда есть запрос, включающий индекс FULLTEXT, MySQL Query Optimizer стремится превратить запрос в полное сканирование таблицы. Я видел это на протяжении многих лет. Я также написал более раннюю статью об этом самом незначительном поведении в индексах FULLTEXT .
Вам может потребоваться сделать две вещи:
РЕФАКТОР ЗАПРОСА
Вот ваш оригинальный запрос
Вам нужно будет реорганизовать запрос следующим образом:
СОЗДАТЬ НОВЫЙ ИНДЕКС
Вам понадобится индекс для поддержки
subqueryA
. У вас уже есть индексtopic_id
. Вам необходимо заменить его следующим образом:Попробуйте!
ОБНОВЛЕНИЕ 2012-03-19 13:08 ПО ВОСТОЧНОМУ ВРЕМЕНИ
Попробуйте это первым
Если это выполняется быстро и возвращает небольшое количество строк, попробуйте этот вложенный подзапрос:
ОБНОВЛЕНИЕ 2012-03-19 13:11 ПО ВОСТОЧНОМУ ВРЕМЕНИ
Сравните время выполнения этого:
с этим
Если время выполнения одинаково, то предложение MATCH выполняется в каждой строке. Как я уже упоминал ранее, использование индексов FULLTEXT приводит к аннулированию любых преимуществ, предпринятых и вносимых оптимизатором запросов MySQL.
источник
post_id
смущает его? Почему запрос LIKE работает даже без индекса для этих столбцов (topic_id, post_id)? Почему MYSQL не просто интеллектуально выбирает,topic_id = 144017 AND post_id != 155352
а затем просто просматривает эти результаты? А что, если в 100 тыс. Строк есть моя строка полнотекстового поискаpost_text
? Разве это не выберет их всех?