Há situações em que é necessário ter uma consulta realmente grande unindo várias tabelas com instruções sub-select para produzir os resultados desejados.
Minha pergunta é: devemos considerar o uso de várias consultas menores e trazer as operações lógicas para a camada de aplicativo consultando o banco de dados em mais de uma chamada ou é melhor tê-las de uma só vez?
Por exemplo, considere a seguinte consulta:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
Qual é a melhor maneira de fazer isso?
fonte
Como alguém que precisa apoiar / limpar essas consultas grandes e complicadas, eu diria que é muito melhor separá-las em vários pequenos pedaços fáceis de entender. Não é necessariamente melhor do ponto de vista de desempenho, mas você está dando ao SQL uma chance melhor de apresentar um bom plano de consulta.
Facilite a vida das pessoas que o seguem, e elas dirão coisas boas a seu respeito. Torne difícil para eles e eles o amaldiçoarão.
fonte
Meus 2 centavos nas 2 palavras-chave consulta desempenho e escalabilidade:
Desempenho da consulta: o paralelismo do SQL Server já faz um trabalho muito bom, dividindo as consultas em pesquisas multithread, por isso não tenho certeza do quanto de melhoria no desempenho da consulta você verá ao fazê-lo no SQL Server. Você precisará examinar o plano de execução para ver quanto grau de paralelismo você obtém ao executá-lo, no entanto, e comparar os resultados nos dois sentidos. Se você precisar usar uma dica de consulta para obter o mesmo ou melhor desempenho, o IMO não valerá a pena, pois a dica de consulta pode não ser ideal posteriormente.
Escalabilidade: a leitura das consultas pode ser mais fácil, como indicado no código de dados, e dividi-las em consultas separadas faz sentido se você pode usar suas novas consultas em outras áreas também, mas se não for usá-las para outras chamadas também, serão ainda mais procs armazenados para gerenciar uma tarefa, e a IMO não contribuirá para a escalabilidade.
fonte
LIMIT
Algumas vezes, não há escolha a não ser dividir a consulta grande / complexa em consultas pequenas. A melhor maneira de determinar isso seria usar a
EXPLAIN
declaração com aSELECT
declaração. O número de rastreamentos / verificações que seu banco de dados fará para buscar seus dados é o produto dos valores de "linhas" retornados por suaEXPLAIN
consulta. No nosso caso, tivemos uma consulta juntando 10 tabelas. Por um registro específico, o rastreamento totalizou 409 milhões de blogs no nosso banco de dados e aumentou o uso da CPU do servidor de banco de dados em mais de 300%. Conseguimos recuperar as mesmas informações dividindo as consultas muito mais rapidamente.Portanto, em suma, em alguns casos, dividir uma consulta complexa / grande faz sentido, mas em outros pode levar a muitos problemas de desempenho ou manutenção e isso deve ser tratado caso a caso.
fonte