MIN / MAX vs ORDER BY e LIMIT

99

Das consultas a seguir, qual método você consideraria o melhor? Quais são seus motivos (eficiência do código, melhor capacidade de manutenção, menos WTFery) ...

SELECT MIN(`field`)
FROM `tbl`;

SELECT `field`
FROM `tbl`
ORDER BY `field`
LIMIT 1;
nickf
fonte

Respostas:

125

No pior caso, quando você está olhando para um campo não indexado, o uso MIN()requer uma única passagem completa da tabela. Usando SORTe LIMITrequer um filesort. Se executado em uma mesa grande, provavelmente haverá uma diferença significativa no desempenho percebido. Como um ponto de dados sem sentido, MIN()demorou 0,36s SORTe LIMIT0,84s contra uma tabela de 106.000 linhas no meu servidor de desenvolvimento.

Se, no entanto, você estiver olhando para uma coluna indexada, a diferença é mais difícil de notar (o ponto de dados sem sentido é 0,00s em ambos os casos). Olhando para a saída de explain, no entanto, parece que MIN()é capaz de simplesmente extrair o menor valor do índice ('Selecionar tabelas otimizadas' e linhas 'NULL') enquanto o SORTe LIMITainda precisa fazer uma travessia ordenada do índice (106.000 linhas). O impacto real no desempenho é provavelmente insignificante.

Parece que MIN()é o caminho a seguir - é mais rápido no pior caso, indistinguível no melhor caso, é SQL padrão e expressa mais claramente o valor que você está tentando obter. O único caso em que parece que usar SORTe LIMITseria desejável seria, como mson mencionou, onde você está escrevendo uma operação geral que encontra os valores N superior ou inferior de colunas arbitrárias e não vale a pena escrever a operação de caso especial.

Sean McSomething
fonte
7
o (n) para uma única passagem vs 0 (nlogn) para classificação
Abhishek Iyer
1
@AbhishekIyer você está totalmente certo, mas eu acrescentaria "no pior caso, para campo não indexado".
dmikam
Essa parte sobre o pior caso não indexado está errada. Você sempre precisa de uma verificação completa, de que outra forma você sabe que é um mínimo ou máximo? Não é como se você estivesse digitalizando e o valor gritasse: "Ei, você finalmente me encontrou! Eu sou Jack, o máximo!".
Robo Robok de
Em um teste com uma tabela indexada com 470 milhões de linhas, ambas as consultas levam 0,00 s. No entanto, se adicionarmos às consultas um filtro "WHERE field2 = x", a consulta com LIMIT ainda leva 0,00 se a consulta com MIN leva 0,21 s.
Antonio Cañas Vargas
12
SELECT MIN(`field`)
FROM `tbl`;

Simplesmente porque é compatível com ANSI. O Limite 1 é específico para MySql, assim como TOP é para SQL Server.

Otávio Décio
fonte
A maioria dos SGBDs tem limite / deslocamento ou equivalente, e é usado na maioria dos aplicativos em que trabalhei (não como uma alternativa ao MIN, mas para outros fins, como paginação).
finnw
@finnw - Eu concordo, mas o exemplo do questionador estava comparando o limite com o min explicitamente.
Otávio Décio
9

Como mson e Sean McSomething apontaram, MIN é preferível.

Um outro motivo pelo qual ORDER BY + LIMIT é útil é se você deseja obter o valor de uma coluna diferente da coluna MIN.

Exemplo:

SELECT some_other_field, field
FROM tbl
ORDER BY field
LIMIT 1
user650654
fonte
4

Acho que as respostas dependem do que você está fazendo.

Se você tiver uma consulta 1 desativada e a intenção for tão simples quanto você especificou, selecione min (campo) é preferível.

No entanto, é comum ter esses tipos de requisitos mudando para - pegue os n primeiros resultados, pegue os n resultados - mésimos, etc.

Não acho que seja uma ideia terrível se comprometer com o banco de dados escolhido. Mudar o banco de dados não deve ser feito levianamente e tem que revisar é o preço que você paga ao fazer esta mudança.

Por que se limitar agora, pela dor que você pode ou não sentir mais tarde?

Eu acho que é bom permanecer ANSI o máximo possível, mas isso é apenas uma diretriz ...

mson
fonte
3

Dado o desempenho aceitável, eu usaria o primeiro porque é semanticamente mais próximo da intenção.
Se o desempenho fosse um problema (a maioria dos otimizadores modernos provavelmente otimizará ambos para o mesmo plano de consulta, embora você precise testar para verificar isso), então é claro que eu usaria o mais rápido.

Charles Bretana
fonte