Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Otimização de consulta MySQL - consultas internas


Você sempre pode usar EXPLAIN ou EXPLAIN EXTENDED para ver o que o MySql está fazendo com uma consulta

Você também pode escrever sua consulta de uma maneira um pouco diferente, já tentou o seguinte?
SELECT        s.*, 
              sm.url AS media_url 
FROM          shows AS s
INNER JOIN    show_medias AS sm ON s.id = SM.show_id
WHERE `s`.`id` IN ( 
                        SELECT DISTINCT st.show_id 
                        FROM show_time_schedules AS sts 
                        LEFT JOIN show_times AS st ON st.id = sts.show_time_id 
                        WHERE sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date) 
                        ) 
AND            `s`.`is_active` = 1 
AND            sm.is_primary = 1
ORDER BY       s.name asc 

Seria interessante ver qual é o efeito disso. Eu esperaria que fosse mais rápido, pois, no momento, acho que o MySql estará executando a consulta interna 1 para cada show que você tiver (para que uma consulta seja executada muitas vezes. Uma junção deve ser mais eficiente.)

Substitua o INNER JOIN por um LEFT JOIN se quiser todos os shows que não tenham uma linha em show_medias.

EDITAR:

Vou dar uma olhada no seu EXPLAIN EXTENDED em breve, também gostaria de saber se você quer tentar o seguinte; ele remove todas as subconsultas:
SELECT        DISTINCT s.*,  
                       sm.url AS media_url  
FROM                   shows AS s 
INNER JOIN             show_medias AS sm ON s.id = SM.show_id
INNER JOIN             show_times AS st ON (s.id = st.show_id)
RIGHT JOIN             show_time_schedules AS sts ON (st.id = sts.show_time_id)

WHERE                  `s`.`is_active` = 1  
AND                    sm.is_primary = 1 
AND                    sts.schedule_date BETWEEN CAST('2012-01-10' AS date) AND CAST('2012-01-14' AS date)  
ORDER BY               s.name asc 

(Também seria bom ver o EXPLAIN EXTENDED nestes - você pode adicioná-lo aos comentários para este).

EDITAR MAIS:

No seu EXPLAIN EXTENDED (um bom começo sobre como ler estes está aqui )

O USING FILESORT e o USING TEMPORARY são indicadores-chave. Espero que a segunda consulta que eu recomendo remova todas as tabelas TEMPORÁRIAS (na subconsulta). Tente então deixar o ORDER BY desligado para ver se isso faz diferença (e podemos adicionar isso às descobertas até agora :-)

Também posso ver que a consulta está potencialmente perdendo muitas pesquisas de índice; todas as suas colunas id são candidatas principais para correspondências de índice (com o usual advertências de índice ). Eu também tentaria adicionar esses índices e, em seguida, executar EXPLAIN EXTENDED novamente para ver qual é a diferença agora (EDIT como já sabemos do seu comentário acima!)