Qual é a diferença entre select count (*) e select count (any_non_null_column)?

58

Eu me lembro que (no Oracle) há uma diferença entre expressar select count(*) from any_tablee select count(any_non_null_column) from any_table.

Quais são as diferenças entre essas duas instruções, se houver?

Martin
fonte

Respostas:

72
  • COUNT (*) incluirá NULLS
  • COUNT (coluna_ou_expressão) não.

Isso significa COUNT(any_non_null_column)que dará o mesmo que é COUNT(*)claro, porque não há valores NULL para causar diferenças.

Geralmente, COUNT(*)deve ser melhor porque qualquer índice pode ser usado porque COUNT(column_or_expression)pode não ser indexado ou SARGable

No ANSI-92 (procure por " Scalar expressions 125")

Caso:

a) Se COUNT (*) for especificado, o resultado será a cardinalidade de T.

b) Caso contrário, seja TX a tabela de coluna única resultante da aplicação da <expressão de valor> a cada linha de T e da eliminação de valores nulos. Se um ou mais valores nulos forem eliminados, uma condição de conclusão será gerada: aviso - valor nulo eliminado na função definida.

As mesmas regras se aplicam ao SQL Server e Sybase também pelo menos

Nota: COUNT (1) é igual a COUNT (*) porque 1 é uma expressão não anulável.

gbn
fonte
4
Apenas para ser completo: o Oracle usará uma varredura de índice em uma coluna indexada não nula se count(*)for usada.
A_horse_with_no_name
Eu pensei que as três opções possíveis foram COUNT(*), COUNT(<constant>)e COUNT(<column name>)e que todos os três poderiam ser prefixados com ALLou DISTINCT(falta para ALLse omitido). Eu só estou querendo saber qual expressão pode ser usada onde você diz _or_expression?
onedaywhen
2
@onedaywhen COUNT(1)como um exemplo inútil, é o mesmo que COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)como um exemplo que conta linhas onde a> b.
ypercubeᵀᴹ
16

Em qualquer versão recente (ou seja, 8.x + ) do Oracle, eles fazem a mesma coisa . Em outras palavras, a única diferença é semântica:

select count(*) from any_table

é facilmente legível e óbvio o que você está tentando fazer, e

select count(any_non_null_column) from any_table

é mais difícil de ler porque

  1. é mais longo
  2. é menos reconhecível
  3. você tem que pensar se any_non_null_columnrealmente é aplicado comonot null

Em resumo, usecount(*)

Jack Douglas
fonte
9

Em uma versão recente, de fato, não há diferença entre count (*) e count ( qualquer coluna que não seja nula ), com ênfase em não nulo :-) Incidentalmente, abordamos esse tópico com uma postagem de blog: É melhor contar do que contar (*)?

Uwe Hesse
fonte
1

No livro Guia do exame de certificação DBA Oracle8i Professional Professional (ISBN 0072130601) , a página 78 diz que COUNT (1) realmente é executado mais rapidamente que COUNT (*) porque certos mecanismos são chamados para verificar o dicionário de dados para a nulidade de todas as colunas (ou pelo menos a primeira coluna com não anulabilidade) ao usar COUNT (*) . COUNT (1) ignora esses mecanismos.

Fraudes do MySQL para 'SELECT COUNT (1) em tblname;' nas tabelas MyISAM lendo o cabeçalho da tabela para a contagem de tabelas. O InnoDB conta sempre.

Para testar se COUNT (1) será executado mais rapidamente que COUNT (*) de maneira independente do banco de dados, basta executar o seguinte e avaliar o tempo de execução:

SELECT COUNT(1) FROM tblname WHERE 1 = 1;
SELECT COUNT(*) FROM tblname WHERE 1 = 1;
SELECT COUNT(column-name) FROM tblname WHERE 1 = 1;

Isso faz com que a função COUNT opere no mesmo campo de atuação, independentemente do mecanismo de armazenamento ou RDBMS.

RolandoMySQLDBA
fonte
8
O guia do exame está errado. No Oracle count (*) = count (1) (pelo menos após a versão 7). Veja asktom.oracle.com/pls/asktom/… (já referenciada por @JackPDouglas)
Leigh Riffel
3
Interessante. COUNT (*) não deve verificar colunas de acordo com a especificação ANSI. Foi convidado no SO para o SQL Server há algum tempo também stackoverflow.com/questions/1221559/count-vs-count1/...
GBN
@gbn, @Leigh Riffel, @bernd_k Obrigado por compartilhar e me lembrar de ler e aprender mais, especialmente porque eu não trabalho com a Oracle há um tempo.
RolandoMySQLDBA