Je vous recommande de rendre vos jointures explicites.
Cela facilite le débogage de votre requête et le changement interne avec des jointures à gauche.
Il n'y a absolument jamais de bonne raison d'utiliser la syntaxe de jointure implicite SQL '89.
SELECT ni.*
, nf.*
, group_concat(nm.mailgroup_name) as mailgroups
FROM newsletter_items ni
INNER JOIN newsletter_fields nf
ON (nf.field_letter_uid = ni.letter_id)
INNER JOIN newsletter_mailgroups nm
ON (find_in_set(nm.mailgroup_id, ni.receivers))
WHERE
nf.field_name = 'letter_headline'
ni.template = '". $template ."'
GROUP BY ni.letter_id;
En ce qui concerne la conception de votre base de données.
Je vous recommande de normaliser votre base de données, cela signifie que vous déplacez les champs séparés par des virgules dans une table différente.
Alors vous faites une table des récepteurs
Receivers
----------
id integer auto_increment primary key
letter_id integer not null foreign key references newsletter_items(letter_id)
value integer not null
Vous supprimez ensuite le récepteur de champ de la table newsletter_items
Votre requête se transforme alors en :
SELECT ni.*
, group_concat(r.value) as receivers
, nf.*
, group_concat(nm.mailgroup_name) as mailgroups
FROM newsletter_items ni
INNER JOIN newsletter_fields nf
ON (nf.field_letter_uid = ni.letter_id)
INNER JOIN newsletter_mailgroups nm
ON (find_in_set(nm.mailgroup_id, ni.receivers))
LEFT JOIN receiver r ON (r.letter_id = ni.letter_id)
WHERE
nf.field_name = 'letter_headline'
ni.template = '". $template ."'
GROUP BY ni.letter_id;
Ce changement devrait également accélérer considérablement votre requête.