Lepiej byłoby przepisać zapytanie jako:
SELECT payments.*
FROM customers
JOIN payments
ON payments.id_customer = customers.id
WHERE customers.id_project = 5
Chociaż wydaje się to mniej zwięzłe, a dobry planista zapytań zobaczy, co próbujesz zrobić, i uruchomi skorelowane zapytanie podrzędne, gdy powyższe połączenie zostanie połączone, zły planista zapytań może w końcu wykonać skanowanie indeksu payments.id_customer
(zakładając, że masz odpowiedni indeks ) (lub, co gorsza, skanowanie tabeli) zamiast robić rzeczy w bardziej wydajny sposób. Nawet dobry planista zapytań może nie zobaczyć optymalizacji, jeśli układ tego zapytania jest zawinięty w coś bardziej skomplikowanego. Wyrażenie relacji jako połączenia zamiast pod-zapytania może mieć większą różnicę niż zmiana struktury danych.
Jak mówi Jeff, wszelkie denormalizacje powinny być rozważane ostrożnie - może przynieść łatwe zwiększenie wydajności, szczególnie w niektórych celach sprawozdawczych, ale może prowadzić do niespójności z powodu błędów w wspierającej logice biznesowej.
Na marginesie: Oczywiście nie znam twojej firmy, więc mogłem coś przeoczyć, ale twoje relacje przy stole wydają mi się dziwne. Sugerują, że nigdy nie można mieć więcej niż jednego projektu z tym samym klientem, co zwykle nie jest prawdą z mojego doświadczenia, przynajmniej przez długi okres.
customer project payment
-------- -------- -------
pa_id
pr_id <-- payment
cu_id <-- customer
lub jeśli jestem mniej znormalizowany (choć wątpię, by to było konieczne):
customer project payment
-------- -------- --------
pa_id
pr_id <-- payment
cu_id <-- customer
`------------- customer
Oczywiście to wciąż dyskontuje możliwość wspólnego projektu z dwoma klientami ...