Qual è la differenza tra select count (*) e select count (any_non_null_column)?


58

Mi sembra di ricordare che (su Oracle) c'è una differenza tra pronunciare select count(*) from any_tablee select count(any_non_null_column) from any_table.

Quali sono le differenze tra queste due affermazioni, se ce ne sono?

Risposte:


72
  • COUNT (*) includerà NULLS
  • COUNT (column_or_expression) no.

Questo significa COUNT(any_non_null_column)che fornirà lo stesso COUNT(*)ovviamente perché non ci sono valori NULL per causare differenze.

In generale, COUNT(*)dovrebbe essere migliore perché è possibile utilizzare qualsiasi indice perché COUNT(column_or_expression)potrebbe non essere indicizzato o SARGable

Da ANSI-92 (cercare " Scalar expressions 125")

Astuccio:

a) Se viene specificato COUNT (*), il risultato è la cardinalità di T.

b) Altrimenti, sia TX la tabella a colonna singola che è il risultato dell'applicazione di <espressione di valore> a ciascuna riga di T e dell'eliminazione di valori nulli. Se uno o più valori null vengono eliminati, viene sollevata una condizione di completamento: avviso - valore null eliminato nella funzione set.

Le stesse regole si applicano almeno a SQL Server e Sybase

Nota: COUNT (1) è uguale a COUNT (*) perché 1 è un'espressione non annullabile.


4
Solo per completezza: Oracle utilizzerà una scansione dell'indice su una colonna indicizzata non nulla se count(*)viene utilizzato.
a_horse_with_no_name

Pensavo che le tre possibili opzioni fossero COUNT(*), COUNT(<constant>)e COUNT(<column name>)che tutti e tre potessero essere preceduti da ( ALLo in DISTINCTdifetto ALLse omessi). Mi sto solo chiedendo quale espressione può essere usata dove dici _or_expression?
Onedayquando il

2
@onedayquando COUNT(1)come esempio inutile, è lo stesso di COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)come esempio che conta le righe in cui a> b.
ypercubeᵀᴹ

16

In qualsiasi versione recente (ovvero 8.x + ) di Oracle fanno la stessa cosa . In altre parole, l'unica differenza è semantica:

select count(*) from any_table

è facilmente leggibile ed evidente cosa stai cercando di fare, e

select count(any_non_null_column) from any_table

è più difficile da leggere perché

  1. è più lungo
  2. è meno riconoscibile
  3. devi pensare se any_non_null_columnè davvero applicato comenot null

In breve, usacount(*)


9

In una versione recente non c'è davvero alcuna differenza tra count (*) e count ( nessuna colonna non nulla ), con l'accento su non null :-) Per inciso ho trattato quell'argomento con un post sul blog: Count (col) è meglio di count (*)?


1

Nel libro Oracle8i Certified Professional DBA Certification Guide Exam (ISBN 0072130601) , pagina 78 dice che COUNT (1) verrà effettivamente eseguito più velocemente di COUNT (*) perché alcuni meccanismi vengono chiamati in gioco per controllare il dizionario dei dati per la nullità di ogni colonna (o almeno la prima colonna con non annullabilità) quando si utilizza COUNT (*) . COUNT (1) ignora questi meccanismi.

Trucchi MySQL per "SELECT COUNT (1) su tblname;" sulle tabelle MyISAM leggendo l'intestazione della tabella per il conteggio delle tabelle. InnoDB conta ogni volta.

Per verificare se COUNT (1) verrà eseguito più rapidamente di COUNT (*) in modo agnostico nel database, basta eseguire quanto segue e giudicare autonomamente il tempo di esecuzione:

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

Questo fa funzionare la funzione COUNT sullo stesso piano di gioco indipendentemente dal motore di archiviazione o dall'RDBMS.


8
La guida agli esami è sbagliata. In Oracle count (*) = count (1) (almeno dopo la versione 7). Vedi asktom.oracle.com/pls/asktom/… (già indicato da @JackPDouglas)
Leigh Riffel

3
Interessante. COUNT (*) non dovrebbe controllare affatto le colonne secondo le specifiche ANSI. Qualche tempo fa è stato chiesto su SO per SQL Server anche stackoverflow.com/questions/1221559/count-vs-count1/…
gbn

@gbn, @Leigh Riffel, @bernd_k Grazie per essere intervenuto e per avermi ricordato di leggere e imparare di più, soprattutto da quando non lavoro con Oracle da un po 'di tempo.
RolandoMySQLDBA
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.