Guarda cosa EXPLAIN EXTENDED
dice.
Se dice DEPENDENT SUBQUERY
o UNCACHEABLE SUBQUERY
, verrà rivalutato ogni volta che viene utilizzato.
Ciò accade se la sottoquery utilizza variabili di sessione o è una sottoquery correlata.
In caso contrario, molto probabilmente verrà memorizzato nella cache.
Se nel tuo caso la sottoquery non verrà memorizzata nella cache, verrà rivalutata in ogni UNION
'ed impostato.
La sottoquery, tuttavia, sembra essere troppo complicata. Perché non usi semplicemente:
SELECT id
FROM playlist_program_map ppm, programs p
WHERE ppm.playlist_id = 181
AND p.id = ppm.program_id
AND submitter_id = 32
AND feed_id = 2478
Se hai un indice su playlist_program_map (playlist_id)
, questa query dovrebbe funzionare come un incantesimo.
Potresti dirmi altre due cose:
- Quante righe ci sono in
playlist_program_map
e quantiDISTINCT playlist_id
i valori ci sono?- Quante righe ci sono in
programs
e quantiDISTINCT submitter_id, feed_id
le coppie ci sono?
- Quante righe ci sono in
Dal tuo commento posso concludere che ce ne sono 10 programs
per playlist
in media e 200 programs
per (submitter, feed)
coppia. Questo significa il tuo indice su playlist_program_map
è più selettivo di quello su (submitter, feed)
e playlist_program_map
deve essere in testa al join.
Anche l'indice fulltext nel tuo caso non sembra essere molto selettivo, dato che devi unirti a 10 programmi su 2.000.000 .
È meglio provare quanto segue:
SELECT object_id, programs.created AS created
FROM playlist_program_map ppm, programs p, comments_programs cp
WHERE ppm.playlist_id = 181
AND p.id = ppm.program_id
AND p.submitter_id = 32
AND p.feed_id = 2478
AND cp.object_id = p.id
AND cp.text REGEXP 'excellent'
, e ripeti l'operazione per tutte e tre le tabelle.