Pergunta

Estou escrevendo um programa que envia um email no horário local específico de um cliente.Eu tenho um método .NET que usa fuso horário, hora e fuso horário de destino e retorna a hora nesse fuso horário.Portanto, meu método é selecionar cada fuso horário distinto no banco de dados, verificar se é o horário correto usando o método e, em seguida, selecionar cada cliente do banco de dados com esse(s) fuso(s) horário(s).

A consulta será semelhante a uma destas.Tenha em mente que a ordem do conjunto de resultados não importa, então uma união seria adequada.Qual deles roda mais rápido ou eles realmente fazem a mesma coisa?

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)

ou

SELECT email FROM tClient WHERE timezoneID = 1
    UNION ALL SELECT email FROM tClient WHERE timezoneID = 4
    UNION ALL SELECT email FROM tCLIENT WHERE timezoneID = 9

Editar: timezoneID é uma chave estrangeira para tTimezone, uma tabela com chave primária timezoneID e campo varchar(20) timezoneName. Além disso, fui com WHERE IN já que não tive vontade de abrir o analisador.

Editar 2: A consulta processa 200 mil linhas em menos de 100 ms, então, neste ponto, terminei.

Foi útil?

Solução

Ei!Essas consultas não são equivalentes.

Os resultados serão os mesmos apenas se assumirmos que um e-mail pertence apenas a um fuso horário.É claro que sim, mas o mecanismo SQL não sabe disso e tenta remover duplicidades.Portanto, a primeira consulta deve ser mais rápida.

Sempre use UNION ALL, a menos que você saiba por que deseja usar UNION.

Se você não tem certeza do que é a diferença, veja esse Então pergunta.

Observação:esse grito pertence a versão anterior de pergunta.

Outras dicas

Para a maioria das questões de desempenho relacionadas ao banco de dados, a verdadeira resposta é executá-lo e analisar o que o banco de dados faz pelo seu conjunto de dados.Execute um plano de explicação ou rastreamento para ver se sua consulta está atingindo os índices adequados ou crie índices, se necessário.

Eu provavelmente escolheria o primeiro usando a cláusula IN, pois ela carrega a maior semântica do que você deseja.O timezoneID parece uma chave primária em alguma tabela de fuso horário, portanto deve ser uma chave estrangeira no email e indexada.Dependendo do otimizador de banco de dados, eu acho que deveria fazer uma varredura de índice no índice de chave estrangeira.

Meu primeiro palpite seria que

SELECT email FROM tClient WHERE timezoneID in (1, 4, 9)
será mais rápido, pois requer apenas uma varredura da tabela para encontrar os resultados, mas sugiro verificar o plano de execução para ambas as consultas.

Não tenho o MS SQL Query Analyzer em mãos para realmente verificar minha hipótese, mas acho que a variante WHERE IN seria mais rápida porque com o servidor UNION será necessário fazer 3 varreduras de tabela, enquanto com WHERE IN será necessário apenas um.Se você tiver o Query Analyzer, verifique os planos de execução para ambas as consultas.

Na Internet, muitas vezes você pode encontrar sugestões para evitar o uso de WHERE IN, mas isso se refere a casos em que subconsultas são usadas.Portanto, este caso está fora do escopo desta recomendação e, além disso, é mais fácil de ler e compreender.

Acho que faltam várias informações muito importantes na pergunta.Em primeiro lugar, é de grande importância que o timezoneID do clima esteja indexado ou não, se faz parte da chave primária, etc.Aconselho a todos que dêem uma olhada no analisador, mas na minha experiência a cláusula WHERE deveria ser mais rápida, especialmente com um índice.A lógica é algo como: há uma sobrecarga adicional na consulta de união, verificando tipos, números de colunas em cada um, etc.

No livro "SQL Performance Tuning", os autores descobriram que as consultas UNION eram mais lentas em todos os 7 SGBDs testados (SQL Server 2000, Sybase ASE 12.5, Oracle 9i, DB2, etc.): http://books.google.com/books?id=3H9CC54qYeEC&pg=PA32&vq=UNION&dq=sql+performance+tuning&source=gbs_search_s&sig=ACfU3U18uYZWYVHxr2I3uUj8kmPz9RpmiA#PPA33,M1

Os DBMS posteriores podem ter otimizado essa diferença, mas é duvidoso.Além disso, o método UNION é muito mais longo e mais difícil de manter (e se você quiser um terceiro?) vs.o IN.

A menos que você tenha um bom motivo para usar UNION, opte pelo método OR/IN.

Alguns otimizadores de consulta do SGBD modificam sua consulta para torná-la mais eficiente; portanto, dependendo do SGBD que você está usando, você provavelmente não deveria se importar.

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