Pergunta

Tem Cadastre consultas mais rápido do que várias consultas? (Você executar a consulta principal, em seguida, executar muitas outras SELECTs com base nos resultados de sua consulta principal)

Estou perguntando porque se juntando a eles complicaria bastante a concepção da minha candidatura

Se eles são mais rápidos, alguém pode aproximar muito aproximadamente por quanto? Se é 1.5x Eu não me importo, mas se é 10x Eu acho que eu faço.

Foi útil?

Solução

Esta é a maneira demasiado vago para lhe dar uma resposta relevante para o seu caso específico. Isso depende de muitas coisas. Jeff Atwood (fundador deste site) realmente escreveu sobre este . Para a maior parte, porém, se você tem os índices certas e você adequadamente fazer o seu JOINs é geralmente vai ser mais rápido para fazer uma viagem de várias.

Outras dicas

Para se junta interna, uma única consulta faz sentido, já que você só obter registros coincidentes. Para esquerda junta-se, várias consultas é muito melhor ... olhada no seguinte referência eu fiz:

  1. consulta individual com 5 junta

    query: 8.074508 segundos

    tamanho do resultado: 2268000

  2. 5 consultas em uma fileira

    tempo de consulta combinados: 0,00262 segundos

    tamanho resultado: 165 (6 + 50 + 7 + 12 + 90)

.

Note que obter os mesmos resultados em ambos os casos (6 x 50 x 7 x 12 x 90 = 2.268.000)

esquerda junta uso exponencialmente mais memória com dados redundantes.

O limite de memória pode não ser tão ruim se você só faz uma junção de duas tabelas, mas geralmente três ou mais e torna-se consultas no valor diferentes.

Como uma nota lateral, o meu servidor MySQL está certo ao lado do meu servidor de aplicativos ... então o tempo de conexão é insignificante. Se o seu tempo de conexão é nos segundos, então talvez haja um benefício

Frank

Na verdade, eu vim a esta pergunta procurando uma resposta a mim mesmo, e depois de ler as respostas dadas só posso concordar que a melhor maneira de comparar o desempenho DB consultas é fazer com que os números do mundo real, porque há apenas para muitas variáveis ??a ser tidos em conta MAS, eu também acho que comparando os números entre eles leva a nada de bom 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 em comparação com os outros.

Eu posso entender se uma forma de consulta leva dizem 0,02 segundos eo outro leva 20 segundos, que é uma enorme diferença. Mas e se uma forma de consulta leva 0.0000000002 segundos, eo outro leva 0.0000002 segundos? Em ambos os casos uma maneira é uma gritante 1000 vezes mais rápido do que o outro, mas é realmente ainda "whopping" no segundo caso?

A linha inferior como eu, pessoalmente, vê-lo:. Se ele funciona bem, ir para a solução fácil

fiz um teste rápido selecionando uma linha de uma tabela fileira 50.000 e juntando-se com uma linha de uma tabela 100.000 linha. Basicamente parecia:

$id = mt_rand(1, 50000);
$row = $db->fetchOne("SELECT * FROM table1 WHERE id = " . $id);
$row = $db->fetchOne("SELECT * FROM table2 WHERE other_id = " . $row['other_id']);

vs

$id = mt_rand(1, 50000);
$db->fetchOne("SELECT table1.*, table2.*
    FROM table1
    LEFT JOIN table1.other_id = table2.other_id
    WHERE table1.id = " . $id);

O selecione o método dois levou 3,7 segundos para 50.000 lê enquanto o JOIN levou 2,0 segundos no meu computador lento em casa. INNER JOIN e LEFT JOIN não fazer a diferença. A obtenção de várias linhas (por exemplo, utilizando EM CONJUNTO) obtiveram resultados semelhantes.

Construir duas consultas separadas e junta-se, então o tempo de cada um deles -. Nada ajuda mais do que números reais

Em seguida, ainda melhor - adicionar "explicar" ao início de cada consulta. Isto irá dizer-lhe quantas subqueries MySQL está usando para responder à sua solicitação de dados, e quantas linhas digitalizados para cada consulta.

Dependendo da complexidade do banco de dados em comparação com a complexidade desenvolvedor, pode ser mais simples de fazer muitas chamadas SELECT.

Tente executar algumas estatísticas de banco de dados contra tanto a juntar-se e os múltiplos selects. Veja se no seu ambiente o JOIN é mais rápido / mais lento do que o SELECT.

Então, novamente, se mudando para um JOIN significaria um extra de dia / semana / mês de trabalho dev, eu ia ficar com múltiplas SELECTs

Cheers,

BLT

A verdadeira questão é:? Será que esses registros têm uma relacionamento one-to-one ou relacionamento um-para-muitos

TLDR Resposta:

Se um-para-um, usar uma instrução JOIN.

Se um-para-muitos, uso um (ou muitos) declarações SELECT com otimização de código do lado do servidor.

Por que e Como Use SELECT para Otimização

SELECT'ing (com várias consultas em vez de junta) em grande grupo de registros com base em uma relação de um-para-muitos produz uma eficiência ideal, como JOIN'ing tem um problema de fuga de memória exponencial. Pegar todos os dados, em seguida, usar uma linguagem de script do lado do servidor para resolver o problema:

SELECT * FROM Address WHERE Personid IN(1,2,3);

Resultado:

Address.id : 1            // First person and their address
Address.Personid : 1
Address.City : "Boston"

Address.id : 2            // First person's second address
Address.Personid : 1
Address.City : "New York"

Address.id : 3            // Second person's address
Address.Personid : 2
Address.City : "Barcelona"

Aqui, eu estou recebendo todos os registros, em uma instrução SELECT. Isto é melhor do que JOIN, que estaria recebendo um pequeno grupo desses registros, um de cada vez, como um sub-componente de outra consulta. Então eu analisá-lo com o código do lado do servidor que é algo como ...

<?php
    foreach($addresses as $address) {
         $persons[$address['Personid']]->Address[] = $address;
    }
?>

Quando não usar Cadastre-se para Otimização

JOIN'ing um grande grupo de registros com base em um relacionamento um-para-um com um único registro produz uma ótima eficiência em comparação com várias instruções SELECT, um após o outro, que simplesmente pegar o próximo tipo de registro.

Mas JOIN é ineficiente quando se registros com um relacionamento um-para-muitos.

Exemplo:. O Blogs banco de dados tem 3 mesas de interesse, BlogPost, Tag, e Comment

SELECT * from BlogPost
LEFT JOIN Tag ON Tag.BlogPostid = BlogPost.id
LEFT JOIN Comment ON Comment.BlogPostid = BlogPost.id;

Se houver um blogpost, 2 tags, e 2 comentários, você vai obter resultados como:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag2, comment1,
Row4: tag2, comment2,

Observe como cada registro é duplicado. Ok, então, 2 comentários e 2 tags é de 4 linhas. E se temos 4 comentários e 4 Tag? Você não ganha 8 linhas - você tem 16 linhas:

Row1: tag1, comment1,
Row2: tag1, comment2,
Row3: tag1, comment3,
Row4: tag1, comment4,
Row5: tag2, comment1,
Row6: tag2, comment2,
Row7: tag2, comment3,
Row8: tag2, comment4,
Row9: tag3, comment1,
Row10: tag3, comment2,
Row11: tag3, comment3,
Row12: tag3, comment4,
Row13: tag4, comment1,
Row14: tag4, comment2,
Row15: tag4, comment3,
Row16: tag4, comment4,

Adicionar mais mesas, mais registros, etc., e que o problema irá inflar rapidamente para centenas de linhas que são todos cheios de principalmente dados redundantes.

O que essas duplicatas custar? Memória (no servidor SQL e o código que tenta remover as duplicatas) e rede recursos (entre o servidor SQL eo servidor de código).

Fonte: https: //dev.mysql .com / doc / refman / 8,0 / en / nested-se juntar-optimization.html ; https://dev.mysql.com/doc/workbench/ en / WB-relação-tools.html

Na minha experiência, eu descobri que é geralmente mais rápido para executar várias consultas, especialmente quando a recuperação de grandes conjuntos de dados.

Ao interagir com o banco de dados de outro aplicativo, como PHP, há o argumento de uma viagem para o servidor através de muitos.

Existem outras maneiras de limitar o número de viagens feitas ao servidor e várias consultas ainda executar que muitas vezes são não só mais rápido, mas também tornar a aplicação mais fácil de ler -. Por exemplo mysqli_multi_query

Eu não sou nenhum novato quando se trata de SQL, eu acho que há uma tendência para os desenvolvedores, especialmente juniores para gastar muito tempo tentando escrever muito inteligente se junta porque eles olhar inteligente, ao passo que existem maneiras realmente inteligentes para extrair dados que olhar simples.

O último parágrafo era uma opinião pessoal, mas eu espero que isso ajude. Eu concordo com os outros, porém, que dizem que você deve benchmark. Nenhuma abordagem é uma bala de prata.

Esta questão é antiga, mas está faltando alguns benchmarks. Eu aferido Cadastre-se contra seus 2 concorrentes:

  • N + 1 consultas
  • 2 consultas, o segundo usando um WHERE IN(...) ou equivalente

O resultado é claro: no MySQL, JOIN é muito mais rápido. N + 1 queries pode soltar o desempenho de um aplicativo drasticamente:

ADERIR vs ONDE EM vs N + 1

Isto é, a menos que você escolha um monte de registros que apontam para um número muito pequeno de registros distintos, estrangeiros. Aqui é um ponto de referência para o caso extremo:

JUNTE-SE vs N + 1 - todos os registros que apontam para o mesmo registro estrangeiro

Isto é muito improvável que isso aconteça em uma aplicação típica, a menos que você está se juntando a um relacionamento -para-muitos, caso em que a chave estrangeira em outra tabela, e você está duplicando os principais dados da tabela muitas vezes.

Leve em conta:

  • Para * -para-um relacionamento, sempre use JOIN
  • Para * relações -para-muitos, uma segunda consulta pode ser mais rápido

meu artigo sobre Medium para mais informações.

Será que vai ser mais rápido em termos de rendimento? Provavelmente. Mas também potencialmente bloqueia mais objetos de banco de dados em um tempo (dependendo do seu banco de dados e seu esquema) e, assim, diminui a simultaneidade. Na minha experiência, as pessoas são muitas vezes enganados pelo argumento de "menos de banco de dados round-trips", quando na realidade na maioria dos sistemas OLTP onde o banco de dados está na mesma rede local, o gargalo real é raramente a rede.

Aqui está um link com 100 consultas úteis, estes são testados no banco de dados Oracle, mas lembre-SQL é um padrão, que diferem entre Oracle, MS SQL Server, MySQL e outros bancos de dados são o dialeto SQL:

http://javaforlearn.com/100-sql-queries-learn/

Há vários fatores que significa que não há resposta binário. A questão do que é melhor para o desempenho depende do seu ambiente. By the way, se a sua escolha individual com um identificador não é sub-segundo, algo pode estar errado com sua configuração.

A verdadeira questão a perguntar é como você deseja acessar os dados. seleciona suporte único a ligação tardia. Por exemplo, se você só quer a informação do empregado, você pode selecionar da tabela Funcionários. As relações de chave estrangeira pode ser usado para recuperar os recursos relacionados em um momento posterior e, conforme necessário. Os seleciona já terá uma chave para o ponto de que eles devem ser extremamente rápido, e você só tem que recuperar o que você precisa. latência de rede deve ser sempre levado em conta.

junta irá recuperar todos os dados de uma vez. Se você estiver gerando um relatório ou preencher uma grade, isso pode ser exatamente o que você quer. Compilado e optomized associações são simplesmente vai ser mais rápido do que seleciona único neste cenário. Lembre-se, Ad-hoc se junta pode não ser tão rápida - você deve compilá-los (em um proc armazenado). A resposta de velocidade depende do plano de execução, que detalha exatamente quais os passos que o DBMS leva para recuperar os dados.

Se você deve usar uma junção é em primeiro lugar sobre se a juntar-se faz sentido . Só nesse momento é um desempenho ainda algo a ser considerado, como quase todos os outros casos resultará em significativa pior performance.

diferenças de desempenho será em grande parte ligada à forma como relacionados com a informação que você está consultando para é. Junta-se o trabalho, e eles são rápidos quando os dados são relacionados e você índice coisas corretamente, mas eles muitas vezes resultam em alguma redundância e às vezes mais resultados do que necessário. E se os seus conjuntos de dados não estão diretamente relacionados, fixá-los em uma única consulta irá resultar no que é chamado um produto cartesiano (basicamente, todas as combinações possíveis de linhas), que quase nunca é o que você quer.

Este é frequentemente causada por muitos-para-um-para-muitos relacionamentos. Por exemplo, a resposta de HoldOffHunger mencionado uma única consulta para mensagens, tags e comentários. Comentários estão relacionados a um poste, como são tags ... mas as tags não estão relacionados aos comentários.

+------------+     +---------+     +---------+
|  comment   |     |   post  |     |  tag    |
|------------|*   1|---------|1   *|---------|
| post_id    |-----| post_id |-----| post_id |
| comment_id |     | ...     |     | tag_id  |
| user_id    |     |         |     | ...     |
| ...        |     |         |     | ...     |
+------------+     +---------+     +---------+

Neste caso, é inequivocamente melhor para que este seja pelo menos duas consultas separadas. Se você tenta ingressar tags e comentários, porque não há nenhuma relação direta entre os dois, você acaba com todas as combinações possíveis de tag e comentários. many * many == manymany. Além de que, uma vez que as mensagens e tags são independentes, você pode fazer essas duas consultas em paralelo, levando ao ganho potencial.

Vamos considerar um cenário diferente, no entanto:. Você quer os comentários anexados a um poste, e dos comentadores informação de contato

 +----------+     +------------+     +---------+
 |   user   |     |  comment   |     |   post  |
 |----------|1   *|------------|*   1|---------|
 | user_id  |-----| post_id    |-----| post_id |
 | username |     | user_id    |     | ...     |
 | ...      |     | ...        |     +---------+
 +----------+     +------------+

Este é o lugar onde você deve considerar uma junção. Além de ser uma consulta muito mais natural, a maioria dos sistemas de banco de dados (incluindo MySQL) têm muitas pessoas inteligentes colocar muito trabalho duro em otimização de consultas exatamente como ele. Para consultas separadas, uma vez que cada consulta depende dos resultados do anterior, as consultas não pode ser feito em paralelo, eo tempo total torna-se não apenas o real executar tempo das consultas, mas também o tempo gasto buscar resultados, peneirando através deles para IDs para a próxima consulta, ligando as linhas juntas, etc.

Sim, uma consulta usando JOINS seria mais rápido. Embora sem saber as relações das tabelas que você está consultando, o tamanho de seu conjunto de dados, ou onde as chaves primárias são, é quase impossível dizer o quanto mais rápido.

Por que não testar ambos os cenários para fora, então você vai saber com certeza ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top