Sie sollten die Abfrage folgendermaßen umschreiben:
SELECT payments.*
FROM customers
JOIN payments
ON payments.id_customer = customers.id
WHERE customers.id_project = 5
Während dies weniger präzise erscheint und ein guter Abfrageplaner erkennt, was Sie versuchen, und Ihre korrelierte Unterabfrage stattdessen als obiger Join ausführt, führt ein schlechter Abfrageplan möglicherweise einen Index-Scan durch payments.id_customer
(vorausgesetzt, Sie haben einen relevanten Index) ) (oder schlimmer noch, das Scannen von Tabellen), anstatt die Dinge auf effizientere Weise zu erledigen. Selbst ein guter Abfrageplaner kann die Optimierung möglicherweise nicht erkennen, wenn die Anordnung dieser Abfrage etwas komplizierter ist. Das Ausdrücken der Beziehung als Join und nicht als Unterabfrage kann mehr bewirken als das Ändern Ihrer Datenstruktur.
Wie Jeff sagt, sollte jede Denormalisierung mit Vorsicht in Betracht gezogen werden - dies kann zu leichten Leistungssteigerungen führen, insbesondere für einige Berichtszwecke, kann jedoch zu Inkonsistenzen aufgrund von Fehlern in der unterstützenden Geschäftslogik führen.
Als Randnotiz: Natürlich kenne ich Ihr Geschäft nicht, daher könnte mir etwas fehlen, aber Ihre Tischbeziehungen scheinen mir seltsam. Sie implizieren, dass Sie nie mehr als ein Projekt mit demselben Kunden haben können, was meiner Erfahrung nach normalerweise nicht der Fall ist, zumindest nicht über einen längeren Zeitraum.
customer project payment
-------- -------- -------
pa_id
pr_id <-- payment
cu_id <-- customer
oder wenn es weniger normalisiert ist (obwohl ich bezweifle, dass dies notwendig wäre):
customer project payment
-------- -------- --------
pa_id
pr_id <-- payment
cu_id <-- customer
`------------- customer
Das schließt natürlich die Möglichkeit eines gemeinsamen Projekts mit zwei Kunden aus ...