Proverei quanto segue:
Innanzitutto, assicurati che siano presenti indici nelle seguenti tabelle e colonne (ogni insieme di colonne tra parentesi dovrebbe essere un indice separato):
table1 : (subscribe, CDate)
(CU_id)
table2 : (O_cid)
(O_ref)
table3 : (I_oref)
(I_pid)
table4 : (P_id)
(P_cat)
table5 : (C_id, store)
Secondo, se l'aggiunta degli indici sopra non ha migliorato le cose quanto vorresti, prova a riscrivere la query come
SELECT DISTINCT t1.first_name, t1.last_name, t1.email FROM
(SELECT CU_id, t1.first_name, t1.last_name, t1.email
FROM table1
WHERE subscribe = 1 AND
CDate >= $startDate AND
CDate <= $endDate) AS t1
INNER JOIN table2 AS t2
ON t1.CU_id = t2.O_cid
INNER JOIN table3 AS t3
ON t2.O_ref = t3.I_oref
INNER JOIN table4 AS t4
ON t3.I_pid = t4.P_id
INNER JOIN (SELECT C_id FROM table5 WHERE store = 2) AS t5
ON t4.P_cat = t5.C_id
Spero qui che la prima sottoselezione riduca significativamente il numero di righe da considerare per l'unione, si spera che i join successivi facciano meno lavoro. Idem il ragionamento alla base della seconda sottoselezione su table5.
In ogni caso, pasticciare. Voglio dire, alla fine è solo un SELECT - non puoi davvero ferire nulla con esso. Esamina i piani generati da ogni diversa permutazione e cerca di capire cosa c'è di buono o cattivo in ciascuno.
Condividi e divertiti.