Recentemente, tive uma discussão com outro desenvolvedor que me afirmou que JOINs (SQL) são inúteis. Isso é tecnicamente verdade, mas ele acrescentou que o uso de junções é menos eficiente do que fazer várias solicitações e tabelas de links no código (C # ou Java).
Para ele, as junções são para pessoas preguiçosas que não se importam com desempenho. Isso é verdade? Devemos evitar o uso de junções?
Respostas:
Não, devemos evitar desenvolvedores que tenham opiniões incrivelmente erradas.
Em muitos casos, uma junção ao banco de dados é várias ordens de magnitude mais rápidas do que qualquer coisa feita através do cliente, porque evita viagens de ida e volta ao banco de dados, e o banco de dados pode usar índices para realizar a junção.
No topo da minha cabeça, nem consigo imaginar um cenário único em que uma junção usada corretamente seria mais lenta que a operação equivalente do lado do cliente.Edit: Existem alguns casos raros em que o código do cliente personalizado pode fazer as coisas com mais eficiência do que uma junção direta ao banco de dados (consulte o comentário por meriton). Mas isso é muito a exceção.
fonte
Parece-me que seu colega faria bem com um banco de dados de documentos no-sql ou um armazenamento de valores-chave. Quais são eles mesmos ferramentas muito boas e adequadas para muitos problemas.
No entanto, um banco de dados relacional é altamente otimizado para trabalhar com conjuntos. Existem muitas, muitas maneiras de consultar os dados com base em junções que são muito mais eficientes do que muitas viagens de ida e volta. É daí que vem a versatilidade de um rdbms. Você também pode obter o mesmo em uma loja nosql, mas geralmente cria uma estrutura separada adequada para cada natureza diferente da consulta.
Em resumo: eu discordo. Em um RDBMS, as junções são fundamentais . Se você não os estiver usando, não o usará como um RDBMS.
fonte
Bem, ele está errado no caso geral.
Os bancos de dados podem otimizar usando uma variedade de métodos, ajudados por dicas do otimizador, índices de tabela, relacionamentos de chave estrangeira e possivelmente outras informações específicas do fornecedor do banco de dados.
fonte
Não, você não deveria.
Os bancos de dados são projetados especificamente para manipular conjuntos de dados (obviamente ...). Portanto, eles são incrivelmente eficientes para fazer isso. Ao fazer o que é essencialmente uma junção manual em seu próprio código, ele está tentando assumir o papel de algo especificamente projetado para o trabalho. As chances de seu código ser tão eficiente quanto o do banco de dados são muito remotas.
Como um aparte, sem junções, qual é o sentido de usar um banco de dados? ele também pode usar arquivos de texto.
fonte
Se "preguiçoso" é definido como pessoas que desejam escrever menos código, então eu concordo. Se "preguiçoso" é definido como pessoas que querem ter ferramentas fazem o que fazem, concordo. Então, se ele está apenas concordando com Larry Wall (sobre os atributos de bons programadores), então eu concordo com ele.
fonte
Ummm, joins é como os bancos de dados relacionais relacionam tabelas entre si. Não sei ao que ele está chegando.
Como fazer várias chamadas ao banco de dados pode ser mais eficiente do que uma chamada? Além disso, os mecanismos sql são otimizados para fazer esse tipo de coisa.
Talvez seu colega de trabalho tenha preguiça de aprender SQL.
fonte
Sim você deveria.
E você deve usar C ++ em vez de C # por causa do desempenho. C # é para pessoas preguiçosas.
Não não não. Você deve usar C em vez de C ++ por causa do desempenho. C ++ é para pessoas preguiçosas.
Não não não. Você deve usar assembly em vez de C por causa do desempenho. C é para pessoas preguiçosas.
Sim, estou brincando. você pode criar programas mais rápidos sem junções e pode criar programas usando menos memória sem junções. MAS, em muitos casos, o tempo de desenvolvimento é mais importante que o tempo e a memória da CPU. Desista de um pouco de desempenho e aproveite sua vida. Não perca seu tempo com pouco desempenho. E diga a ele: "Por que você não faz uma estrada reta do seu lugar para o seu escritório?"
fonte
"Isso é tecnicamente verdadeiro" - da mesma forma, um banco de dados SQL é inútil: qual é o sentido de usar um quando você pode obter o mesmo resultado usando vários arquivos CSV e correlacionando-os no código? Caramba, qualquer abstração é para pessoas preguiçosas, vamos voltar à programação em código de máquina diretamente no hardware! ;)
Além disso, sua afirmação é falsa em todos os casos, exceto nos mais complicados: os RDBMSs são fortemente otimizados para tornar os JOINs rápidos . Sistemas de gerenciamento de banco de dados relacional , certo?
fonte
unnecessary
em vezuseless
na frase anterior. Dizer que as junções são inúteis é evidentemente falso, sem necessidade de considerações técnicas. Em qualquer caso, o equívoco do colega do ponto de RDBMSs do OP e é sandly não é incomum: stackoverflow.com/q/5575682/47550A última empresa em que trabalhei também não utilizava junções SQL. Em vez disso, eles moveram esse trabalho para a camada de aplicativo, projetada para ser dimensionada horizontalmente. A lógica para esse design é evitar o trabalho na camada de banco de dados. Geralmente é o banco de dados que se torna gargalo. É mais fácil replicar a camada de aplicativo do que o banco de dados. Pode haver outras razões. Mas este é o que eu me lembro agora.
Sim, eu concordo que as junções feitas na camada de aplicativo são ineficientes em comparação com as junções feitas pelo banco de dados. Mais comunicação em rede também.
Observe que não estou adotando uma postura rígida para evitar junções SQL.
fonte
Sem junções, como você relacionará itens de pedidos com pedidos? Esse é o objetivo de um sistema de gerenciamento de banco de dados relacional. Sem junções, não há dados relacionais e você também pode usar arquivos de texto para processar dados.
Parece que ele não entende o conceito, então ele está tentando fazer parecer que eles são inúteis. Ele é o mesmo tipo de pessoa que acha que o Excel é um aplicativo de banco de dados. Dê um tapa nele e diga a ele para ler mais sobre bancos de dados. Fazer várias conexões e extrair dados e mesclar os dados via C # é a maneira errada de fazer as coisas.
fonte
Não entendo a lógica da instrução "junções no SQL são inúteis". É útil filtrar e limitar os dados antes de trabalhar nele? Como os outros respondentes afirmaram que é isso que os mecanismos de banco de dados fazem, deve ser no que eles são bons.
Talvez um programador preguiçoso se atenha às tecnologias com as quais está familiarizado e evite outras possibilidades por razões não técnicas.
Deixo para você decidir.
fonte
Vamos considerar um exemplo: uma tabela com registros de fatura e uma tabela relacionada com registros de itens de linha de fatura. Considere o pseudocódigo do cliente:
Se você tiver 100.000 faturas com 10 linhas cada, esse código procurará 10 linhas de fatura em uma tabela de 1 milhão e fará isso 100.000 vezes. À medida que o tamanho da tabela aumenta, o número de operações selecionadas aumenta, e o custo de cada operação de seleção aumenta.
Como os computadores são rápidos, você pode não notar uma diferença de desempenho entre as duas abordagens se tiver vários milhares de registros ou menos. Como o aumento de custo é mais do que linear, à medida que o número de registros aumenta (para milhões, digamos), você começará a notar uma diferença, e a diferença se tornará menos tolerável à medida que o tamanho do conjunto de dados aumentar.
A junção, no entanto. usará os índices da tabela e mesclará os dois conjuntos de dados. Isso significa que você está efetivamente digitalizando a segunda tabela uma vez, em vez de acessá-la aleatoriamente N vezes. Se houver uma chave estrangeira definida, o banco de dados já terá os links entre os registros relacionados armazenados internamente.
Imagine fazer isso sozinho. Você tem uma lista alfabética de alunos e um caderno com todos os relatórios das notas dos alunos (uma página por turma). O bloco de notas é classificado em ordem pelo nome dos alunos, na mesma ordem que a lista. Como você prefere continuar?
Ou:
fonte
Parece um caso clássico de " Eu posso escrever melhor ". Em outras palavras, ele está vendo algo que vê como uma dor no pescoço (escrevendo várias junções no SQL) e dizendo "Tenho certeza de que posso escrever melhor e obter melhor desempenho". Você deve perguntar a ele se ele é a) mais inteligente eb) mais instruído do que a pessoa comum que conhece profundamente o código de otimização do Oracle ou SQL Server. As probabilidades são de que ele não é.
fonte
Ele certamente está errado. Embora existam profissionais definidos para manipulação de dados em linguagens como C # ou Java, as junções são mais rápidas no banco de dados devido à natureza do próprio SQL.
O SQL continua detalhando estatísticas sobre os dados e, se você criou seus índices corretamente, pode encontrar rapidamente um registro em alguns milhões. Além do fato de que, por que você deseja arrastar todos os seus dados para o C # para fazer uma junção, basta fazê-lo no nível do banco de dados?
Os profissionais para usar o C # entram em ação quando você precisa fazer algo iterativamente. Se você precisar executar alguma função para cada linha, provavelmente será mais rápido fazê-lo no C #; caso contrário, a junção de dados será otimizada no banco de dados.
fonte
Vou dizer que me deparei com um caso em que era mais rápido quebrar a consulta e fazer as junções no código. Dito isto, foi apenas com uma versão específica do MySQL que eu tive que fazer isso. Tudo o resto, o banco de dados provavelmente será mais rápido (observe que talvez você precise otimizar as consultas, mas ainda será mais rápido).
fonte
Eu suspeito que ele tenha uma visão limitada sobre para que bancos de dados devem ser usados. Uma abordagem para maximizar o desempenho é ler todo o banco de dados na memória. Nessa situação, você pode obter um desempenho melhor e pode querer realizar junções se houver memória para obter eficiência. No entanto, isso realmente não está usando um banco de dados, como um IMHO de banco de dados.
fonte
MEMORY
mecanismo). Reimplementar a funcionalidade do banco de dados sem o banco de dados geralmente é um sinal de um caso grave de NIH;)Não, as junções não são apenas melhor otimizadas no código do banco de dados que C # / Java ad-hoc; mas geralmente várias técnicas de filtragem podem ser aplicadas, o que gera um desempenho ainda melhor.
fonte
Ele está errado, junta-se ao que os programadores competentes usam. Pode haver alguns casos limitados em que o método proposto é mais eficiente (e naqueles que eu provavelmente usaria um banco de dados Documant), mas não consigo vê-lo se você tiver uma quantidade enganosa de dados. Por exemplo, faça esta consulta:
Suponha que você tenha 10 milhões de registros na tabela1 e 1 milhão de registros na tabela2. Suponha que 9 milhões de registros na tabela 1 atendam à cláusula where. Suponha que apenas 15 deles estejam na tabela2 também. Você pode executar esta instrução sql que, se indexada corretamente, levará milissegundos e retornará 15 registros pela rede com apenas 1 coluna de dados. Ou você pode enviar dez milhões de registros com 2 colunas de dados e enviar separadamente outros 1 milhão de registros com uma coluna de dados pela rede e combiná-los no servidor da web.
Ou, é claro, você pode manter todo o conteúdo do banco de dados no servidor da Web o tempo todo, o que é simplesmente bobo se você tiver mais do que uma quantidade trivial de dados e dados que estão mudando continuamente. Se você não precisa das qualidades de um banco de dados relacional, não use um. Mas se você o fizer, use-o corretamente.
fonte
Eu ouvi esse argumento muitas vezes durante minha carreira como desenvolvedor de software. Quase sempre que foi declarado, o sujeito que fez a reclamação não tinha muito conhecimento sobre sistemas de bancos de dados relacionais, a maneira como eles funcionam e a forma como esses sistemas devem ser usados.
Sim, quando usado incorretamente , as junções parecem inúteis ou até perigosas. Porém, quando usado da maneira correta, existe muito potencial para a implementação do banco de dados executar otimizações e "ajudar" o desenvolvedor a recuperar o resultado correto com mais eficiência.
Não se esqueça de que usando um
JOIN
você diz ao banco de dados como espera que os dados se relacionem entre si e, portanto, fornece ao banco de dados mais informações sobre o que você está tentando fazer e, portanto, é capaz de atender melhor às suas necessidades.Portanto, a resposta é definitivamente: Não,
JOINS
não é inútil!fonte
Isso é "tecnicamente verdadeiro" apenas em um caso que não é usado com freqüência em aplicativos (quando todas as linhas de todas as tabelas nas junções são retornadas pela consulta). Na maioria das consultas, apenas uma fração das linhas de cada tabela é retornada. O mecanismo de banco de dados geralmente usa índices para eliminar as linhas indesejadas, às vezes mesmo sem ler a linha real, pois pode usar os valores armazenados nos índices. O mecanismo de banco de dados é ele próprio escrito em C, C ++ etc. e é pelo menos tão eficiente quanto o código escrito por um desenvolvedor.
fonte
A menos que eu tenha entendido seriamente, a lógica da pergunta é muito falha
Se houver 20 linhas em B para cada A, 1000 linhas em A implicarão 20k em B. Não pode haver apenas 100 linhas em B, a menos que haja muitas tabelas "AB" com 20k linhas contendo o mapeamento .
Portanto, para obter todas as informações sobre quais 20 das 100 linhas B são mapeadas para cada linha A, você também apresenta a tabela AB. Portanto, isso seria:
Portanto, "JOIN" no cliente adiciona algum valor quando você examina os dados. Não que não seja uma má ideia. Se eu estava recuperando um objeto do banco de dados, talvez faça mais sentido decompô-lo em conjuntos de resultados separados. Para uma chamada do tipo relatório, eu a dividia em uma quase sempre.
De qualquer forma, eu diria que quase não há utilidade para uma junção cruzada dessa magnitude. É um péssimo exemplo.
Você precisa se juntar a algum lugar, e é nisso que o RDBMS é bom. Eu não gostaria de trabalhar com nenhum macaco de código de cliente que pense que pode fazer melhor.
Reflexão tardia:
Para ingressar no cliente, são necessários objetos persistentes, como DataTables (em .net). Se você tiver um conjunto de resultados nivelado, ele poderá ser consumido por algo mais leve, como um DataReader. Volume alto = muitos recursos do cliente usados para evitar um JOIN do banco de dados.
fonte