AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 196158
Accepted
Jacob Barnes
Jacob Barnes
Asked: 2018-01-25 11:40:43 +0800 CST2018-01-25 11:40:43 +0800 CST 2018-01-25 11:40:43 +0800 CST

WHERE vs. HAVING em colunas não agregadas. Vantagens / Desvantagens / Irrelevantes?

  • 772

Estou no processo de reescrever consultas que não extraem mais todos os dados necessários. Minha pergunta é em relação a uma prática que nunca vi e não encontrei nenhuma pergunta no StackExchange que aborde especificamente o problema.

Eu sei que o objetivo da HAVINGdeclaração é introduzir condições em agregações, assim como WHEREintroduz condições em linhas individuais. No entanto, o que estou vendo neste código está HAVINGsendo usado em vez de WHEREconsultas com agregações. As condições em HAVINGnão são aplicadas nas agregações, mas nas colunas não agregadas.

Por exemplo:

SELECT id, filedate, SUM(amount)
FROM Sales
GROUP BY id, filedate
HAVING id = 123 AND filedate = '1/1/2018'

Ao contrário de:

SELECT id, filedate, SUM(amount)
FROM Sales
WHERE id = 123 AND filedate = '1/1/2018'
GROUP BY id, filedate

Existem implicações de desempenho ou outras vantagens/desvantagens para esta estratégia?

Eu não tentei executar diagnósticos por conta própria, não é uma prioridade e teria que fazer isso no meu próprio tempo. No entanto, acho que posso, se não houver uma resposta clara sobre isso.

Minha preocupação é como o otimizador visualiza essa consulta. Ele agrega todos os dados e, em seguida, restringe o conjunto de resultados com base na HAVINGcláusula ou percebe que pode aplicar as condições de ter nas linhas individuais, pois elas estão referenciando especificamente colunas não agregadas?

EDIT: Para minhas consultas de exemplo e o SQL real que estou reescrevendo, os planos são idênticos, mas as consultas são de complexidade semelhante e ainda não tenho conhecimento suficiente para tirar conclusões dos planos idênticos.

sql-server t-sql
  • 2 2 respostas
  • 7305 Views

2 respostas

  • Voted
  1. Best Answer
    Solomon Rutzky
    2018-01-25T11:52:56+08:002018-01-25T11:52:56+08:00

    As condições em HAVINGnão são aplicadas nas agregações, mas nas colunas não agregadas.

    O problema aqui está em como você está descrevendo a que a HAVINGcláusula se aplica. A HAVINGcláusula sempre se aplica a campos agregados , que são todas as colunas restantes após a agregação. Você está tentando mostrar/dizer que a HAVINGcláusula não está sendo aplicada a nenhuma função agregada , que é o que eles geralmente aplicam. Mas, na realidade, a HAVINGcláusula rege o resultado dessa função agregada ou, em seu primeiro exemplo, o resultado da coluna de agrupamento. Mas em ambos os casos, a agregação já foi realizada.

    Portanto, em termos de desempenho (sem mencionar a legibilidade para outras pessoas tentando atualizar este código posteriormente), você usa a WHEREcláusula para filtrar o que será agregado e, em seguida, a HAVINGcláusula para filtrar o que foiagregado. E, embora o resultado de um teste simples, como mostrado na pergunta, mascare a diferença entre o tempo dos dois (ou o posicionamento lógico na sequência em que a consulta é processada) de modo que "parecem" estar fazendo a mesma coisa, Eu ficaria bastante surpreso se não fosse menos eficiente agregar um monte de linhas apenas para jogá-las fora mais tarde, quando logicamente elas poderiam ter sido eliminadas antes de armazenar/computar as agregações. NO ENTANTO, se você ver que os planos de execução são semelhantes para este exemplo simples, estou disposto a apostar que é apenas devido ao otimizador ver que seria mais eficiente tornar essas HAVINGcondições reaisWHEREcondições à medida que reescreve a consulta antes de executá-la. Mas, nesse caso, eu ainda desaconselharia escrever consultas dessa maneira porque você está fazendo com que o otimizador demore mais tempo para reescrever código ruim quando deveria estar gastando esse tempo / ciclos de CPU encontrando um plano mais eficiente. @DavidSpillett acrescentou (em um comentário sobre esta resposta): "Além disso, você está confiando no planejador de consultas vendo o potencial de otimização, que pode não ser em consultas mais complexas ou se seu código acabar sendo portado para outro banco de dados (ou mesmo apenas um versão mais antiga do SQL Server)".

    Por que vale a pena, até mesmo a documentação da Microsoft para a cláusula HAVING afirmava que ela agia como uma WHEREcláusula quando não GROUP BYestava presente. Agora que a documentação está no GitHub, consegui corrigi-la recentemente via Pull Request #235: Corrigir e melhorar a cláusula HAVING .

    • 16
  2. jyao
    2018-01-25T12:18:36+08:002018-01-25T12:18:36+08:00

    Solomon dá explicações muito boas, mas para mim, a resposta fácil é lembrar a ordem de processamento lógico da consulta SQL como Itzik Ben-Gan escreveu aqui A sequência é sempre

    FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY

    Então veja, se pudermos ter um filtro WHERE aplicado antes de GROUP BY, podemos reduzir a quantidade de dados a serem processados ​​por GROUP BY, esp, a operação WHERE pode ser extremamente eficiente quando existem índices adequados. Como tal, eu diria que se usar WHERE e HAVING retornam o mesmo resultado da perspectiva do negócio, WHERE é sempre um vencedor sobre HAVING.

    • 11

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve