Como otimizar uma consulta SQL contendo UNION
Olá a todos,
Preciso otimizar a consulta MySQLi abaixo, A consulta é para exibir posts relacionados, estava funcioando tranquilo mas ultimamente o blog aumentou as visitas, aí começou a pesar a consulta, levando atualmente em média 0.4917s o que é um tempo absurdo para cada consulta. Preciso de ajuda pra tentar chegar em 0.04s no máximo a consulta.
Segue o código SQL:
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE wp_term_relationships.term_taxonomy_id = '254' AND `wp_posts`.`ID` != '10768' AND wp_posts.post_status = 'publish'
ORDER BY RAND() LIMIT 2 )
UNION ALL
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE wp_term_relationships.term_taxonomy_id = '112' AND `wp_posts`.`ID` != '10768' AND wp_posts.post_status = 'publish'
ORDER BY RAND() LIMIT 2 )
UNION ALL
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE `wp_posts`.`ID` != '10768' AND wp_posts.post_status = 'publish' AND (wp_posts.linguagem != 'en')
ORDER BY RAND() LIMIT 8)
LIMIT 8
Acredito que se acharmos uma solução, isso poderá no futuro ajudar pessoas com o mesmo problema.
#-- ATUALIZAÇÕES --# Depois de muito trabalho descobri que o que estava deixando minha consulta lenta não era nem o rand(), mas sim a consulta ao "post_status" e adicionando para ele buscar antes o tipo do post "post_type" a consulta ficou muito mais rápida, cerca de 0,035s no total o que ficou num valor aceitavel pra mim
Consulta Atualizada:
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE wp_term_relationships.term_taxonomy_id = '254' AND `wp_posts`.`ID` != '10768' AND wp_posts.post_status = 'publish'
ORDER BY RAND() LIMIT 2 )
UNION ALL
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE wp_term_relationships.term_taxonomy_id = '112' AND `wp_posts`.`ID` != '10768' AND wp_posts.post_status = 'publish'
ORDER BY RAND() LIMIT 2 )
UNION ALL
( SELECT ID,post_name,post_update FROM `wp_posts`
INNER JOIN `wp_term_relationships` ON `wp_term_relationships`.`object_id` = `wp_posts`.`ID`
WHERE `wp_posts`.`ID` != '10768' AND wp_posts.post_type = 'post' AND wp_posts.post_status = 'publish' AND (wp_posts.linguagem != 'en')
ORDER BY RAND() LIMIT 8)
LIMIT 8
Talvez essa tabela "post_status" esteja precisando de um OPTIMIZE TABLE mas ainda não me sinto seguro para usar essa função com medo de perder meus dados.
Realmente é necessario fazer isto com o union?
minha sugestão:
SELECT ID ,post_name ,post_update FROM wp_posts INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID WHERE wp_term_relationships.term_taxonomy_id IN ('254', '112') AND wp_posts.ID != '10768' AND wp_posts.post_status = 'publish' AND wp_posts.linguagem != 'en' ORDER BY RAND() LIMIT 8;
Provavelmente essa consulta que fiz tera melhor desempenho porque em comparação com a primeira consulta, utilizei operador "IN" ao invés de várias cláusulas "UNION ALL". Além disso, a clausa where roda somente uma vez, em vez de rodar tres vezes.
bom dia, chegou a testar alguma outra solução? ou quer uma explicação de como otimizar query's?
SELECT ID, post_name, post_update
FROM (
SELECT ID, post_name, post_update, 1 AS sort_order
FROM wp_posts
INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID
WHERE wp_term_relationships.term_taxonomy_id = '254'
AND wp_posts.post_status = 'publish'
AND wp_posts.ID != '10768'
UNION
SELECT ID, post_name, post_update, 2 AS sort_order
FROM wp_posts
INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID
WHERE wp_term_relationships.term_taxonomy_id = '112'
AND wp_posts.post_status = 'publish'
AND wp_posts.ID != '10768'
UNION
SELECT ID, post_name, post_update, 3 AS sort_order
FROM wp_posts
INNER JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID
WHERE wp_posts.post_status = 'publish'
AND wp_posts.ID != '10768'
AND wp_posts.linguagem != 'en'
) AS subquery
ORDER BY RAND()
LIMIT 8;