Quelle est la différence entre select count (*) et select count (any_non_null_column)?


58

Il me semble me souvenir que (sur Oracle) il y a une différence entre prononcer select count(*) from any_tableet select count(any_non_null_column) from any_table.

Quelles sont les différences entre ces deux déclarations, le cas échéant?

Réponses:


72
  • COUNT (*) comprendra NULLS
  • COUNT (column_or_expression) ne le fera pas.

Cela signifie que vous COUNT(any_non_null_column)obtiendrez la même chose que COUNT(*)bien sûr car il n'y a pas de valeur NULL pouvant causer des différences.

En règle générale, COUNT(*)devrait être mieux car tout index peut être utilisé car COUNT(column_or_expression)ne peut être indexé ou SARGable

À partir de ANSI-92 (recherchez " Scalar expressions 125")

Cas:

a) Si COUNT (*) est spécifié, le résultat est la cardinalité de T.

b) Sinon, laissez TX être le tableau à colonne unique résultant de l'application de l'expression <value expression> à chaque ligne de T et de l'élimination des valeurs nulles. Si une ou plusieurs valeurs nulles sont éliminées, une condition d'achèvement est alors créée: warning - valeur nulle éliminée dans la fonction set.

Les mêmes règles sont applicables à SQL Server et Sybase aussi au moins

Remarque: COUNT (1) est identique à COUNT (*) car 1 est une expression non Nullable.


4
Juste pour être complet: Oracle utilisera une analyse d'index sur une colonne indexée non NULL si elle count(*)est utilisée.
a_horse_with_no_name

Je pensais que les trois options possibles étaient COUNT(*), COUNT(<constant>)et COUNT(<column name>)que toutes les trois pourraient être préfixées par ALLou DISTINCT(par défaut à ALLomises). Je me demande simplement quelle expression peut être utilisée où vous dites _or_expression?
onedaywhen

2
@onedayQuand COUNT(1)un exemple inutile, c'est le même que COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)à titre d'exemple, qui compte les lignes où a> b.
Ypercubeᵀᴹ

16

Dans toute version récente (c.-à-d. 8.x + ) d’Oracle, ils font la même chose . En d'autres termes, la seule différence est sémantique:

select count(*) from any_table

est facile à lire et à comprendre ce que vous essayez de faire, et

select count(any_non_null_column) from any_table

est plus difficile à lire parce que

  1. c'est plus long
  2. c'est moins reconnaissable
  3. vous devez réfléchir à savoir si any_non_null_columnest vraiment appliquée commenot null

En bref, utilisezcount(*)



1

Dans le livre Oracle8i Certified Professional Guide d’examen de certification DBA (ISBN 0072130601) , page 78 indique que COUNT (1) sera plus rapide que COUNT (*), car certains mécanismes sont mis en œuvre pour vérifier le dictionnaire de données pour la nullité de chaque colonne (ou au moins la première colonne avec non-nullability) lorsqu’on utilise COUNT (*) . COUNT (1) contourne ces mécanismes.

MySQL triche pour 'SELECT COUNT (1) on tblname;' sur les tables MyISAM en lisant l’en-tête du nombre de tables. InnoDB compte à chaque fois.

Pour tester si COUNT (1) fonctionnera plus vite que COUNT (*) d'une manière agnostique à la base de données, il suffit d'exécuter ce qui suit et d'évaluer le temps d'exécution par vous-même:

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

Cela permet à la fonction COUNT de fonctionner sur le même pied d'égalité, quel que soit le moteur de stockage ou le SGBDR.


8
Le guide d'examen est faux. Dans Oracle, nombre (*) = nombre (1) (au moins après la version 7). See asktom.oracle.com/pls/asktom/… (Déjà référencé par @JackPDouglas)
Leigh Riffel

3
Intéressant. COUNT (*) ne doit absolument pas vérifier les colonnes conformément à la spécification ANSI. A été demandé sur le SO pour SQL Server il y a quelque temps trop stackoverflow.com/questions/1221559/count-vs-count1/...
gbn

@gbn, @Leigh Riffel, @bernd_k Merci de m'avoir rappelé et de me rappeler de lire et d'en apprendre plus, en particulier parce que je ne travaille pas avec Oracle depuis un moment.
RolandoMySQLDBA
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.