Ответ Джейсона точен. Кроме того, я бы попытался использовать более современный синтаксис объединения ANSI, чтобы снять нагрузку с предложения WHERE, чтобы избежать путаницы:
SELECT o.id
FROM programs o
JOIN titles_programs t ON t.object_id=o.id
JOIN descriptions_programs d ON d.object_id=o.id
WHERE MATCH (d.text) AGAINST ('+china' IN BOOLEAN MODE) AND d.current=1
OR MATCH (t.text) AGAINST ('+china' IN BOOLEAN MODE) AND t.current=1
Это остановит случайное перекрестное соединение, вызывающее комбинаторный взрыв; Я ожидаю, что он будет работать в разумные сроки, если база данных не будет действительно огромной.
Если нет, можете ли вы опубликовать результаты EXPLAIN SELECT из вышеперечисленного? Предположительно, один или оба полнотекстовых индекса не используются. Я, конечно, мог бы вообразить, что оптимизатор запросов не может использовать второй полнотекстовый индекс, делая что-то вроде попытки «заполнить» строки, которые не соответствуют первому полнотекстовому запросу, вместо перехода прямо к индексу или что-то в этом роде.
Обычно, когда вы хотите использовать полнотекстовый индекс для двух столбцов в комбинации, вы создаете один индекс для обоих столбцов. В любом случае это будет намного быстрее. Однако это будет означать, что вы должны поместить названия и описания в одну таблицу. Это может быть не так сложно: так как полный текст работает только для таблиц MyISAM (и вы обычно не хотите, чтобы ваши канонические данные в таблицах MyISAM), вы можете хранить точную копию ваших данных в должным образом нормализованных таблицах InnoDB с дополнительной таблицей MyISAM содержит только раздетую и остановленную поисковую приманку.
Если ничего из этого не принесет пользы ... ну, я думаю, я бы вернулся к упомянутому вами UNIONing в сочетании с фильтром уровня приложения для удаления дублирующихся идентификаторов.