grupo SQL por contra distinta
-
06-07-2019 - |
Pergunta
Por que alguém iria usar um grupo de contra distinta quando não há agregações feitas na consulta?
Além disso, alguém sabe o grupo, contra considerações de desempenho distintas em MySQL e SQL Server. Eu estou supondo que o SQL Server tem um otimizador de melhor e eles podem estar perto de equivalente lá, mas no MySQL, espero uma vantagem de desempenho significativa para distinto.
Estou interessado em respostas de DBA.
EDIT:
Depois de Bill é interessante, mas não é aplicável. Deixe-me ser mais específico ...
select a, b, c
from table x
group by a, b,c
contra
select distinct a,b,c
from table x
Solução
Um pouco (muito pouco) dados empíricos de MS SQL Server, em um par de tabelas aleatórias de nosso DB.
Para o padrão:
SELECT col1, col2 FROM table GROUP BY col1, col2
e
SELECT DISTINCT col1, col2 FROM table
Quando não há índice de cobertura para a consulta, em ambos os sentidos produziu o seguinte plano de consulta:
|--Sort(DISTINCT ORDER BY:([table].[col1] ASC, [table].[col2] ASC))
|--Clustered Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]))
e quando havia um índice de cobertura, ambos produzidos:
|--Stream Aggregate(GROUP BY:([table].[col1], [table].[col2]))
|--Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]), ORDERED FORWARD)
de modo que desde aquela pequena amostra SQL Server certamente trata ambos o mesmo.
Outras dicas
GROUP BY
mapeia grupos de linhas para uma linha, por valor distinto em específica colunas, que nem sequer têm necessariamente de estar na lista de seleção.
SELECT b, c, d FROM table1 GROUP BY a;
Esta consulta é SQL legal ( Correção: apenas em MySQL, na verdade não é SQL padrão e não é suportado por outras marcas). MySQL aceita-lo, e ele está confiante de que você sabe o que está fazendo, selecionando b
, c
e d
de forma inequívoca, porque eles são dependências funcionais de a
.
No entanto, Microsoft SQL Server e outras marcas não permitem esta consulta, porque ele não pode determinar as dependências funcionais facilmente. Editar: Em vez disso, o padrão SQL requer que você siga o Regra Single-Valor , ou seja, todas as colunas na lista de seleção deve ou ser nomeado na cláusula GROUP BY
ou então ser um argumento para uma função set.
Considerando DISTINCT
sempre olha para todas as colunas na lista de seleção, e apenas aquelas colunas. É um equívoco comum que DISTINCT
permite que você especifique as colunas:
SELECT DISTINCT(a), b, c FROM table1;
Apesar dos parênteses Fazendo a olhar DISTINCT
como chamada de função, não é. É uma opção de consulta e um valor distinto em qualquer um dos três campos da lista de seleção levará a uma linha distinta no resultado da consulta. Uma das expressões neste select-lista tem parênteses em torno dele, mas isso não afetará o resultado.
No MySQL eu encontrei usando um GROUP BY é muitas vezes melhor em desempenho do que distintos.
Fazendo uma "EXPLICAR select distinct" mostra "Usando onde; Usando temporário". MySQL irá criar uma tabela temporária
vs um "EXPLAIN SELECT a, b, c, de T1, T2, onde T2.A = GRUPO T1.A por um" apenas mostra "Using onde"
Ambos geraria o mesmo plano de consulta em MS SQL Server .... Se você tiver MS SQL Server você pode simplesmente permitir que o plano de execução real para ver qual é o melhor para suas necessidades ...
Por favor, dê uma olhada no esses lugares:
http://www.sqlmag.com/Article/ArticleID/24282 /sql_server_24282.html
Se você realmente está procurando valores distintos, as diferentes marcas do código fonte mais legível (como se é parte de um procedimento armazenado) Se eu estou escrevendo consultas ad-hoc eu vou geralmente começam com o grupo por, mesmo se eu tiver nenhuma agregação, porque eu vou muitas vezes acabam colocando-os.