La réponse de Jason est juste. De plus, j'essaierais d'utiliser la syntaxe de jointure ANSI plus moderne pour alléger la charge de la clause WHERE afin de dissiper la confusion :
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
Cela empêchera la jointure croisée par inadvertance de provoquer une explosion combinatoire ; Je m'attendrais à ce qu'il fonctionne dans un délai raisonnable à moins que la base de données ne soit vraiment énorme.
Si non, pouvez-vous publier les résultats d'un EXPLAIN SELECT de ce qui précède ? Vraisemblablement, l'un ou les deux index de texte intégral ne sont pas utilisés. Je pourrais certainement imaginer que l'optimiseur de requête n'utilise pas le deuxième index de texte intégral, en faisant quelque chose comme essayer de "remplir" les lignes qui ne correspondent pas à la première requête de texte intégral au lieu d'aller directement à l'index, ou quelque chose comme ça.
Normalement, lorsque vous souhaitez indexer le texte intégral sur deux colonnes en combinaison, vous créez un index sur les deux colonnes. Ce serait en tout cas beaucoup plus rapide. Cependant, cela signifierait que vous devez mettre les titres et les descriptions dans le même tableau. Ce n'est peut-être pas si difficile :puisque le texte intégral ne fonctionne que sur les tables MyISAM (et que vous ne voulez généralement pas que vos données canoniques soient dans les tables MyISAM), vous pouvez conserver la copie définitive de vos données dans des tables InnoDB correctement normalisées, avec une table MyISAM supplémentaire. ne contenant que des appâts de recherche dépouillés et découragés.
Si rien de tout cela n'est bon... eh bien, je suppose que je reviendrais à l'UNIONing que vous avez mentionné, couplé à un filtre au niveau de l'application pour supprimer les ID en double.