Судя по структуре запроса тормоза скорее всего из-за поиска в тексте.
1) попробуйте использовать индекс FULLTEXT
2) проверьте на всякий случай наличие индексов на числовых полях; для анализа запроса можно использовать EXPLAIN
3) возможно стоит, как вы и писали, нормализовать структуру таблиц, чтобы текстовый поиск поменять на поиск по ID; это был бы самый надежный способ; как например вы сделали здесь (это удачное решение):
and class_ads.category_id in (239,241,242,243,245,246,248,249,201)
4) в крайнем случае, когда от текстового поиска совсем не уйти, можно применить функцию CRC32(), которая подсчитывает контрольную сумму по строке и эту контрольную сумму сохранить в числовом поле `crc`, по полю построить индекс:
CREATE TABLE `table` (
`crc` INT UNSIGNED NOT NULL DEFAULT '0',
`word` VARCHAR(30) NOT NULL DEFAULT '' COLLATE 'utf8mb4_unicode_ci',
INDEX (`crc`);
Потом в запросе искать так:
SELECT * FROM `table` WHERE (`crc`=CRC32(`слово')) AND (`word`='слово');
Но п.4 скорее всего не ваш случай. Я думаю п.3 (создание справочников и выполнение поиска по id) был бы лучшим решением.