Лечится. Только не так просто. Поскольку уже сталкивался с такой проблемой. Ускорение достигнуто на два порядка. Только надо поработать.
Выкладываю в том варианте, как мы решали.
Вариант 1.
Самый легкий - за счет дополнительной памяти. Много не даст, но даст возможность быстро попробовать. В ib_body или в отдельной таблице храниться копия текста - только заранее преобразованная в lower case. Памяти в два раза больше тратиться, insert немного помедленнее, но LOWER(s.post) уходит из запроса, так как делается раз и навсегда.
Вариант 2.
Создается словарь, где слова это первые несколько букв. У нас было 4 для английского. Описывать подробнее не буду, т.к. практически эквивалентен следующему варианту, а именно он дал выигрыш.
Вариант 3.
Создаются следующие 2 таблицы:
code text
CREATE TABLE `dictionary`
(
`id` int(10) NOT NULL auto_increment,
`word` varchar(32),
PRIMARY KEY (`id`)
UNIQUE KEY `id_2` (`word`)
) TYPE=MyISAM DEFAULT CHARSET=utf8
CREATE TABLE 'wordlink'
(
'word_id' NOT NULL,
'body_id' NOT NULL,
KEY 'word_first ('word_id'),
KEY 'body_first'('body_id')
) TYPE=MyISAM
Теперь, пишеться небольная дописка к форуму. Каждый раз при новом посте, пост разбирается на слова, которые приводятся к lowercase и все вставляются в словарь. Поскольку там есть unique key, то ошибки дубляжа можно не обрабатывать. Слова (как определит их Рома) будут входить один раз. Количество слов будет велико, но умеренно велико - с учетом грамматических ошибок. Далее поиск будет идти не по LIKE %xxx%, а по LIKE xxx% - что гораздо быстрее. Иными словами - никаких поисков по подслову. Чаще всего он и не нужен. Это самая главная часть. После этого убийца примет вид (c учетом просто join-ов):
code text
SELECT p.pid
FROM ib_posts p, dictionary d, wordlink l
WHERE d.word LIKE 'тб-7%'
AND l.word_id = d.id
AND l.body_id = p.pid
AND p.forum_id IN (3)
AND p.queued <> 1
Вставка будет выглядеть как:
1. принять сообщение
2. вставить сообщение
3. получить pid сообщения.
4. разбрать на слова.
5. каждое слово найти словаре - с его id. Если слова нет, то вставить и получить его id. Создать запись в wordlink пары (id,pid).
Предыдущее содержимое базы обрабатывается аналогично. Правила по разборке текста на слова должны быть одинаковы и для поиска (когда пользователь ввел строку для поиска) и для разбиения поста и занисения его в словарь.
Я пол-года убил, чтобы убедить наших сделать так. Работает до сих пор с 1997 года.