Eu recomendo que você torne suas junções explícitas.
Isso torna mais fácil depurar sua consulta e alterar as junções internas com junções à esquerda.
Nunca há uma boa razão para usar a sintaxe de junção implícita do 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;
Com relação ao design do seu banco de dados.
Recomendo que você normalize seu banco de dados, isso significa que você mova os campos separados por vírgulas para uma tabela diferente.
Então você faz uma mesa de receptores
Receivers
----------
id integer auto_increment primary key
letter_id integer not null foreign key references newsletter_items(letter_id)
value integer not null
Você então remove o receptor de campo da tabela
newsletter_items
Sua consulta então muda para:
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;
Essa alteração também deve acelerar significativamente sua consulta.