Se eu tiver uma mesa
CREATE TABLE users (
id int(10) unsigned NOT NULL auto_increment,
name varchar(255) NOT NULL,
profession varchar(255) NOT NULL,
employer varchar(255) NOT NULL,
PRIMARY KEY (id)
)
e quero obter todos os valores exclusivos de profession
campo, o que seria mais rápido (ou recomendado):
SELECT DISTINCT u.profession FROM users u
ou
SELECT u.profession FROM users u GROUP BY u.profession
?
Respostas:
Eles são essencialmente equivalentes entre si (na verdade, é assim que alguns bancos de dados implementam
DISTINCT
sob o capô).Se um deles for mais rápido, será
DISTINCT
. Isso ocorre porque, embora os dois sejam iguais, um otimizador de consulta precisaria entender o fato de que seuGROUP BY
não está aproveitando nenhum membro do grupo, apenas as chaves deles.DISTINCT
torna isso explícito, para que você possa se safar com um otimizador um pouco mais burro.Em caso de dúvida, teste!
fonte
DISTINCT
e aGROUP BY
diferença dissoDISTINCT
não precisam classificar a saída e,GROUP BY
por padrão, sim. No entanto, no MySQL, mesmo umDISTINCT
+ aindaORDER BY
pode ser mais rápido que um, devido às dicas extras para o otimizador, conforme explicado pelo SquareCog.GROUP BY
Se você tem um índice em
profession
, esses dois são sinônimos.Caso contrário, use
DISTINCT
.GROUP BY
emMySQL
classifica os resultados. Você pode até fazer:e organize suas profissões em
DESC
ordem.DISTINCT
cria uma tabela temporária e a usa para armazenar duplicatas.GROUP BY
faz o mesmo, mas classifica os resultados distintos posteriormente.assim
é mais rápido, se você não tiver um índice
profession
.fonte
ORDER BY NULL
aoGROUP BY
para evitar a classificação.Todas as respostas acima estão corretas, no caso de DISTINCT em uma única coluna vs GROUP BY em uma única coluna. Todo mecanismo db tem sua própria implementação e otimizações, e se você se preocupa com a pouca diferença (na maioria dos casos), precisa testar contra um servidor específico E uma versão específica! Como as implementações podem mudar ...
MAS, se você selecionar mais de uma coluna na consulta, o DISTINCT será essencialmente diferente! Porque neste caso, ele comparará TODAS as colunas de todas as linhas, em vez de apenas uma coluna.
Então, se você tem algo como:
É um erro comum pensar que a palavra-chave DISTINCT distingue linhas pela primeira coluna especificada, mas a DISTINCT é uma palavra-chave geral dessa maneira.
Portanto, as pessoas precisam ter cuidado para não aceitar as respostas acima como corretas para todos os casos ... Você pode ficar confuso e obter resultados errados enquanto tudo o que queria era otimizar!
fonte
Escolha o mais simples e o mais curto possível - DISTINCT parece ser mais o que você está procurando, apenas porque lhe dará EXATAMENTE a resposta que você precisa e somente isso!
fonte
Agrupar por é mais caro que Distinto, pois Agrupar faz uma classificação no resultado, enquanto distinto o evita. Mas se você deseja criar grupo, produza o mesmo resultado que distinto, dê ordem por nulo .
é igual a
fonte
SELECT profession FROM users GROUP BY profession
bem distinto pode ser mais lento que o grupo em algumas ocasiões no postgres (não conheço outros dbs).
exemplo testado:
http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks_I
por isso tem cuidado ... :)
fonte
Parece que as consultas não são exatamente as mesmas. Pelo menos para o MySQL.
Comparar:
A segunda consulta fornece adicionalmente "Using filesort" no Extra.
fonte
ORDER BY NULL
àGROUP BY
versão e eles serão os mesmos.No MySQL "
Group By
" usa um passo extra:filesort
. Percebo queDISTINCT
é mais rápido do queGROUP BY
, e isso foi uma surpresa.fonte
Após testes pesados, chegamos à conclusão de que o GROUP BY é mais rápido
SELECT sql_no_cache opnamegroep_intern FROM
telwerken
WHEREopnemergroep
IN (7,8,9,10,11,12,13) agrupar por opnamegroep_intern635 total 0,0944 segundos Registros de van Weergave 0 - 29 (635 total, consulta dupla 0,0484 s)
SELECT sql_no_cache distinct (opnamegroep_intern) FROM
telwerken
WHEREopnemergroep
IN (7,8,9,10,11,12,13)635 total 0,2117 segundos (quase 100% mais lento) Registros de van 0 - 29 (635 total, consulta dupla 0,3468 s)
fonte
(mais uma nota funcional)
Há casos em que você precisa usar o GROUP BY, por exemplo, se deseja obter o número de funcionários por empregador:
Nesse cenário
DISTINCT u.employer
, não funciona direito. Talvez exista um caminho, mas eu simplesmente não o conheço. (Se alguém souber fazer essa consulta com DISTINCT, adicione uma observação!)fonte
Aqui está uma abordagem simples que imprimirá os 2 tempos decorridos diferentes para cada consulta.
OU tente SET STATISTICS TIME (Transact-SQL)
Ele simplesmente exibe o número de milissegundos necessário para analisar, compilar e executar cada instrução como abaixo:
fonte
Isto não é uma regra
Para cada consulta .... tente separadamente e agrupe por ... compare o tempo para concluir cada consulta e use o mais rápido ....
Em meu projeto, em algum momento, uso grupo por e outros distintos
fonte
Se você não precisar executar nenhuma função de grupo (soma, média, etc, caso deseje adicionar dados numéricos à tabela), use SELECT DISTINCT. Eu suspeito que seja mais rápido, mas não tenho nada para mostrar.
De qualquer forma, se você estiver preocupado com a velocidade, crie um índice na coluna.
fonte
SELECT DISTINCT será sempre o mesmo ou mais rápido que um GROUP BY. Em alguns sistemas (por exemplo, Oracle), pode ser otimizado para ser o mesmo que DISTINCT na maioria das consultas. Em outros (como o SQL Server), pode ser consideravelmente mais rápido.
fonte
Se o problema permitir, tente com EXISTS, pois ele é otimizado para terminar assim que um resultado é encontrado (e não armazena nenhuma resposta); portanto, se você está apenas tentando normalizar dados para uma cláusula WHERE como esta
Uma resposta mais rápida seria:
Isso nem sempre é possível, mas quando disponível, você verá uma resposta mais rápida.
fonte