Seria melhor reescrever a consulta como:
SELECT payments.*
FROM customers
JOIN payments
ON payments.id_customer = customers.id
WHERE customers.id_project = 5
Embora isso pareça menos conciso e um bom planejador de consultas veja o que você está tentando fazer e execute sua subconsulta correlacionada como a junção acima, um planejador de consultas ruim pode acabar fazendo uma varredura de índice payments.id_customer
(supondo que você tenha um índice relevante ) (ou pior, varredura de tabela) em vez de fazer as coisas da maneira mais eficiente. Mesmo um bom planejador de consultas pode não conseguir ver a otimização se o arranjo dessa consulta estiver envolvido em algo mais complicado. Expressar o relacionamento como uma junção em vez de uma subconsulta pode fazer mais diferença do que alterar sua estrutura de dados.
Como Jeff diz, qualquer desnormalização deve ser considerada com cuidado - isso pode proporcionar um aumento fácil no desempenho, principalmente para fins de geração de relatórios, mas pode levar à inconsistência devido a erros na lógica comercial de suporte.
Como uma observação lateral: obviamente eu não conheço o seu negócio, então poderia estar perdendo alguma coisa, mas o seu relacionamento com a mesa me parece estranho. Elas implicam que você nunca pode ter mais de um projeto com o mesmo cliente, o que geralmente não é verdade na minha experiência, pelo menos por um longo período.
customer project payment
-------- -------- -------
pa_id
pr_id <-- payment
cu_id <-- customer
ou se estiver sendo menos normalizado (embora eu duvide que seja necessário):
customer project payment
-------- -------- --------
pa_id
pr_id <-- payment
cu_id <-- customer
`------------- customer
Claro que isso ainda desconta a possibilidade de um projeto conjunto com dois clientes ...