As consultas JOIN são mais rápidas que as várias consultas? (Você executa sua consulta principal e, em seguida, executa muitos outros SELECTs com base nos resultados da consulta principal)
Estou perguntando porque JUNTAR a eles complicaria MUITO o design do meu aplicativo
Se forem mais rápidos, alguém pode se aproximar mais ou menos em quanto? Se é 1,5x, eu não ligo, mas se é 10x, acho que sim.
mysql
database
join
query-optimization
Thomas Bonini
fonte
fonte
Respostas:
Isso é muito vago para fornecer uma resposta relevante ao seu caso específico. Isso depende de muitas coisas. Jeff Atwood (fundador deste site) realmente escreveu sobre isso . Na maioria das vezes, se você tem os índices corretos e faz corretamente seus JOINs, geralmente será mais rápido fazer uma viagem do que várias.
fonte
Para junções internas, uma única consulta faz sentido, pois você só obtém linhas correspondentes. Para associações à esquerda, várias consultas são muito melhores ... veja o seguinte benchmark que eu fiz:
Consulta única com 5 junções
consulta: 8.074508 segundos
tamanho do resultado: 2268000
5 consultas seguidas
tempo combinado da consulta: 0,00262 segundos
tamanho do resultado: 165 (6 + 50 + 7 + 12 + 90)
.
Observe que obtemos os mesmos resultados nos dois casos (6 x 50 x 7 x 12 x 90 = 2268000)
junções esquerdas usam exponencialmente mais memória com dados redundantes.
O limite de memória pode não ser tão ruim se você fizer apenas uma junção de duas tabelas, mas geralmente três ou mais e se tornar consultas diferentes.
Como observação lateral, meu servidor MySQL está ao lado de meu servidor de aplicativos ... portanto, o tempo de conexão é insignificante. Se o seu tempo de conexão for em segundos, talvez haja um benefício
Frank
fonte
Esta pergunta é antiga, mas faltam alguns parâmetros de referência. Comparei o JOIN com seus 2 concorrentes:
WHERE IN(...)
ou equivalenteO resultado é claro: no MySQL,
JOIN
é muito mais rápido. As consultas N + 1 podem diminuir drasticamente o desempenho de um aplicativo:Ou seja, a menos que você selecione muitos registros que apontam para um número muito pequeno de registros estrangeiros distintos. Aqui está uma referência para o caso extremo:
É muito improvável que isso aconteça em um aplicativo típico, a menos que você esteja ingressando em um relacionamento com muitos, nesse caso a chave estrangeira está na outra tabela e você está duplicando os dados da tabela principal muitas vezes.
Leve embora:
JOIN
Veja meu artigo no Medium para obter mais informações.
fonte
Na verdade, eu mesmo cheguei a essa pergunta procurando uma resposta e, depois de ler as respostas, só posso concordar que a melhor maneira de comparar o desempenho das consultas ao banco de dados é obter números do mundo real, porque há muitas variáveis a serem levadas em consideração MAS, também acho que comparar os números entre eles não leva a nada em quase todos os casos. O que quero dizer é que os números devem sempre ser comparados com um número aceitável e definitivamente não são comparados entre si.
Eu posso entender se uma maneira de consultar leva, digamos, 0,02 segundos e a outra leva 20 segundos, é uma enorme diferença. Mas e se uma maneira de consultar demorar 0,0000000002 segundos e a outra demorar 0,0000002 segundos? Nos dois casos, uma maneira é gritante 1000 vezes mais rápida que a outra, mas ainda é realmente "gritante" no segundo caso?
Resumindo, na minha opinião pessoal: se tiver um bom desempenho, escolha a solução mais fácil.
fonte
Fez um teste rápido selecionando uma linha de uma tabela de 50.000 linhas e juntando-se a uma linha de uma tabela de 100.000 linhas. Basicamente, parecia:
vs
O método de seleção dois levou 3,7 segundos para 50.000 leituras, enquanto o JOIN levou 2,0 segundos no meu computador lento em casa. INNER JOIN e LEFT JOIN não fizeram diferença. A busca de várias linhas (por exemplo, usando IN SET) produziu resultados semelhantes.
fonte
A verdadeira questão é: esses registros têm um relacionamento um para um ou um para muitos ?
Resposta TLDR:
Se um para um, use uma
JOIN
declaração.Se um para muitos, use uma (ou muitas)
SELECT
instruções com a otimização de código do lado do servidor.Por que e como usar o SELECT para otimização
SELECT
'(com várias consultas em vez de junções) em um grande grupo de registros com base em um relacionamento um para muitos produz uma eficiência ideal, poisJOIN
há um problema de vazamento de memória exponencial. Pegue todos os dados e use uma linguagem de script do lado do servidor para classificá-los:Resultados:
Aqui, estou obtendo todos os registros, em uma instrução select. Isso é melhor que
JOIN
, o que seria obter um pequeno grupo desses registros, um de cada vez, como subcomponente de outra consulta. Então eu o analiso com o código do servidor que se parece com ...Quando não usar JOIN para otimização
JOIN
um grande grupo de registros com base em um relacionamento individual com um único registro produz uma eficiência ideal em comparação com váriasSELECT
instruções, uma após a outra, que simplesmente obtêm o próximo tipo de registro.Mas
JOIN
é ineficiente ao obter registros com um relacionamento de um para muitos.Exemplo: os blogs do banco de dados têm 3 tabelas de interesse, postagem no blog, tag e comentário.
Se houver 1 postagem no blog, 2 tags e 2 comentários, você obterá resultados como:
Observe como cada registro é duplicado. Ok, então, 2 comentários e 2 tags são 4 linhas. E se tivermos 4 comentários e 4 tags? Você não tem 8 linhas - você tem 16 linhas:
Adicione mais tabelas, mais registros, etc., e o problema aumentará rapidamente para centenas de linhas cheias de dados principalmente redundantes.
Quanto custam essas duplicatas? Memória (no servidor SQL e o código que tenta remover as duplicatas) e recursos de rede (entre o servidor SQL e o servidor de código).
Fonte: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
fonte
Construa consultas e uniões separadas e cronometre cada uma delas - nada ajuda mais do que números do mundo real.
Melhor ainda - adicione "EXPLAIN" ao início de cada consulta. Isso informará quantas subconsultas o MySQL está usando para responder à sua solicitação de dados e quantas linhas varridas para cada consulta.
fonte
Dependendo da complexidade do banco de dados em comparação com a complexidade do desenvolvedor, pode ser mais simples fazer muitas chamadas SELECT.
Tente executar algumas estatísticas do banco de dados no JOIN e no SELECTS múltiplo. Veja se, no seu ambiente, o JOIN é mais rápido / mais lento que o SELECT.
Por outro lado, se alterá-lo para um JOIN significaria um dia / semana / mês extra de trabalho para desenvolvedor, eu ficaria com vários SELECTs
Felicidades,
BLT
fonte
Na minha experiência, descobri que geralmente é mais rápido executar várias consultas, especialmente ao recuperar grandes conjuntos de dados.
Ao interagir com o banco de dados de outro aplicativo, como o PHP, há o argumento de uma viagem ao servidor entre várias.
Existem outras maneiras de limitar o número de viagens feitas ao servidor e ainda executar várias consultas que geralmente não são apenas mais rápidas, mas também facilitam a leitura do aplicativo - por exemplo, mysqli_multi_query.
Não sou novato no que diz respeito ao SQL, acho que há uma tendência para os desenvolvedores, especialmente os juniores, gastarem muito tempo tentando escrever junções muito inteligentes porque parecem inteligentes, enquanto existem maneiras inteligentes de extrair dados com aparência simples.
O último parágrafo foi uma opinião pessoal, mas espero que isso ajude. Eu concordo com os outros que dizem que você deveria fazer benchmark. Nenhuma das abordagens é uma bala de prata.
fonte
Se você deve usar uma junção, é antes de tudo uma questão de saber se uma junção faz sentido . Somente nesse ponto o desempenho é algo a ser considerado, pois quase todos os outros casos resultam em desempenho significativamente pior .
As diferenças de desempenho estarão em grande parte relacionadas à relação das informações que você está consultando. As junções funcionam e são rápidas quando os dados estão relacionados e você indexa as coisas corretamente, mas geralmente resultam em redundância e, às vezes, mais resultados do que o necessário. E se seus conjuntos de dados não estiverem diretamente relacionados, colocá-los em uma única consulta resultará no que é chamado de produto cartesiano (basicamente, todas as combinações possíveis de linhas), o que quase nunca é o que você deseja.
Isso geralmente é causado por relacionamentos muitos-para-um-para-muitos. Por exemplo, a resposta do HoldOffHunger mencionou uma única consulta para postagens, tags e comentários. Os comentários estão relacionados a uma postagem, assim como as tags ... mas as tags não estão relacionadas aos comentários.
Nesse caso, é inequivocamente melhor que sejam pelo menos duas consultas separadas. Se você tentar juntar tags e comentários, porque não há uma relação direta entre os dois, você terá todas as combinações possíveis de tag e comentário.
many * many == manymany
. Além disso, como as postagens e tags não são relacionadas, você pode fazer essas duas consultas em paralelo, levando a um ganho potencial.Vamos considerar um cenário diferente: você deseja que os comentários sejam anexados a uma postagem e as informações de contato dos comentaristas.
É aqui que você deve considerar uma associação. Além de ser uma consulta muito mais natural, a maioria dos sistemas de banco de dados (incluindo o MySQL) tem muitas pessoas inteligentes dedicando muito trabalho na otimização de consultas como essa. Para consultas separadas, uma vez que cada consulta depende dos resultados da anterior, as consultas não podem ser feitas em paralelo e o tempo total torna-se não apenas o tempo de execução real das consultas, mas também o tempo gasto na busca de resultados, peneirando através deles para IDs para a próxima consulta, vinculando linhas, etc.
fonte
Será mais rápido em termos de taxa de transferência? Provavelmente. Mas também potencialmente bloqueia mais objetos de banco de dados ao mesmo tempo (dependendo do seu banco de dados e seu esquema) e, portanto, diminui a simultaneidade. Na minha experiência, as pessoas geralmente são enganadas pelo argumento "menos viagens de ida e volta ao banco de dados" quando, na realidade, na maioria dos sistemas OLTP em que o banco de dados está na mesma LAN, o gargalo real raramente é a rede.
fonte
Aqui está um link com 100 consultas úteis, que são testadas no banco de dados Oracle, mas lembre-se de SQL é um padrão, o que difere entre Oracle, MS SQL Server, MySQL e outros bancos de dados é o dialeto SQL:
http://javaforlearn.com/100-sql-queries-learn/
fonte
Existem vários fatores, o que significa que não há resposta binária. A questão do que é melhor para o desempenho depende do seu ambiente. A propósito, se sua seleção única com um identificador não for um segundo, algo pode estar errado com sua configuração.
A verdadeira pergunta é como você deseja acessar os dados. As seleções únicas suportam ligação tardia. Por exemplo, se você deseja apenas informações de funcionários, é possível selecionar na tabela Funcionários. Os relacionamentos de chave estrangeira podem ser usados para recuperar recursos relacionados posteriormente e conforme necessário. As seleções já terão uma chave para apontar, portanto devem ser extremamente rápidas e você só precisa recuperar o que precisa. A latência da rede sempre deve ser levada em consideração.
As junções recuperam todos os dados de uma só vez. Se você estiver gerando um relatório ou preenchendo uma grade, pode ser exatamente isso que você deseja. Junções compiladas e otimizadas simplesmente serão mais rápidas do que as seleções únicas nesse cenário. Lembre-se, as junções ad-hoc podem não ser tão rápidas - você deve compilá-las (em um processo armazenado). A resposta rápida depende do plano de execução, que detalha exatamente quais etapas o DBMS executa para recuperar os dados.
fonte
Sim, uma consulta usando JOINS seria mais rápida. Embora sem conhecer os relacionamentos das tabelas que você está consultando, o tamanho do seu conjunto de dados ou onde estão as chaves primárias, é quase impossível dizer o quanto mais rápido.
Por que não testar os dois cenários, você saberá com certeza ...
fonte