792 votes

Count(*) vs Count(1) - SQL Server

Je me demandais juste si l'un d'entre vous utilise Count(1) sur Count(*) et s'il y a une différence notable dans les performances ou s'il s'agit simplement d'une habitude héritée des temps passés ?

La base de données spécifique est SQL Server 2005 .

8 votes

Je ne connais pas SQL Server mais dans MySQL il n'y a pas de différence. COUNT(colonne), par contre, est différent.

127 votes

C'est faux. COUNT(SomeColumn) retournera uniquement le nombre de lignes qui contiennent des valeurs non nulles pour SomeColumn. COUNT(*) et COUNT('Foo') retourneront le nombre total de lignes dans le tableau.

1 votes

Pour plus de détails, consultez ce document select count 1 vs select count * en détail avec graphique

639voto

gbn Points 197263

Il n'y a pas de différence.

Raison :

Livres en ligne dit " COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } ) "

"1" est une expression non nulle : c'est donc la même chose que COUNT(*) . L'optimiseur le reconnaît pour ce qu'il est : trivial.

La même chose que EXISTS (SELECT * ... o EXISTS (SELECT 1 ...

Ejemplo:

SELECT COUNT(1) FROM dbo.tab800krows
SELECT COUNT(1),FKID FROM dbo.tab800krows GROUP BY FKID

SELECT COUNT(*) FROM dbo.tab800krows
SELECT COUNT(*),FKID FROM dbo.tab800krows GROUP BY FKID

Même IO, même plan, les travaux

Edit, août 2011

Question similaire sur DBA.SE .

Edit, déc. 2011

COUNT(*) est mentionné spécifiquement dans ANSI-92 (cherchez " Scalar expressions 125 ")

Cas :

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

En d'autres termes, la norme ANSI reconnaît qu'il est évident de saigner ce que vous voulez dire. COUNT(1) a été optimisé par les vendeurs de SGBD. porque de cette superstition. Sinon, il serait évalué selon l'ANSI

b) Sinon, que TX soit la table à une seule colonne qui est la résultat de l'application de l'expression <valeur> à chaque ligne de T et en éliminant les valeurs nulles. Si une ou plusieurs valeurs nulles sont éliminées, alors une condition d'achèvement est levée : warning-

75voto

Quassnoi Points 191041

Dans SQL Server, ces instructions donnent les mêmes plans.

Contrairement à ce que l'on pense, c'est aussi le cas d'Oracle.

SYS_GUID() dans Oracle est une fonction qui demande beaucoup de calculs.

Dans ma base de données de test, t_even est un tableau avec 1,000,000 rangées

Cette requête :

SELECT  COUNT(SYS_GUID())
FROM    t_even

pour 48 secondes, puisque la fonction doit évaluer chaque SYS_GUID() retourné pour s'assurer qu'il ne s'agit pas d'un NULL .

Cependant, cette requête :

SELECT  COUNT(*)
FROM    (
        SELECT  SYS_GUID()
        FROM    t_even
        )

court pour mais 2 secondes, puisqu'elle n'essaie même pas d'évaluer SYS_GUID() (malgré * étant l'argument pour COUNT(*) )

0 votes

Il doit évaluer SYS_GUID() au moins (je veux dire, exactement) une fois pour que la sous-requête renvoie le résultat, n'est-ce pas ?

0 votes

@asgs : pourquoi pensez-vous cela ? Comment le COUNT(*) dépendent des valeurs de SYS_GUID ?

0 votes

Maintenant que vous le demandez, je ne suis pas sûr. Je pensais que pour COUNT(*) pour s'exécuter, elle a besoin d'une table, donc la sous-requête doit agir comme telle. Sinon, je ne vois pas de moyen pour que COUNT(*) pour retourner une valeur significative

69voto

Tony Andrews Points 67363

Clairement, COUNT(*) y COUNT(1) se toujours renvoient le même résultat. Par conséquent, si l'une était plus lente que l'autre, ce serait effectivement dû à un bug de l'optimiseur. Comme les deux formes sont très fréquemment utilisées dans les requêtes, il serait insensé qu'un SGBD permette qu'un tel bug ne soit pas corrigé. Vous constaterez donc que les performances des deux formes sont (probablement) identiques dans tous les principaux SGBD SQL.

4 votes

Je ne considérerais pas que c'est un bug si count(1) était plus lent que count(*). Si vous demandez au dbms de générer des 1 et de compter ceux qui ne sont pas nuls, alors oui, cela revient à compter les enregistrements, mais vous ne pouvez pas vous attendre à ce que le dbms détecte toutes les absurdités que vous écrivez et les contourne pour vous.

2 votes

Eh bien, un optimiseur est censé optimiser et pour un comptage, il n'y a que deux cas à considérer : l'expression qui peut être nulle, l'expression qui ne sera jamais nulle : count(1) tombe dans le dernier cas, donc il n'est pas nécessaire que le SGBD "génère" des 1 pour répondre à la question. (BTW je n'utiliserais jamais autre chose que count(*), juste pour des raisons esthétiques).

22voto

onedaywhen Points 24594

Dans la norme SQL-92, COUNT(*) signifie spécifiquement "la cardinalité de l'expression de la table" (il peut s'agir d'une table de base, d'un `VIEW, d'une table dérivée, d'un CTE, etc).

Je suppose que l'idée était que COUNT(*) est facile à analyser. L'utilisation de toute autre expression nécessite que l'analyseur syntaxique s'assure qu'elle ne fait pas référence à des colonnes ( COUNT('a') donde a est un littéral et COUNT(a) donde a est une colonne peut donner des résultats différents).

Dans la même veine, COUNT(*) peuvent être facilement repérés par un codeur humain connaissant les normes SQL, une compétence utile lorsqu'on travaille avec l'offre SQL de plusieurs fournisseurs.

De plus, dans le cas particulier SELECT COUNT(*) FROM MyPersistedTable; En effet, le SGBD est susceptible de détenir des statistiques sur la cardinalité de la table.

Par conséquent, parce que COUNT(1) y COUNT(*) sont sémantiquement équivalents, j'utilise COUNT(*) .

1 votes

Texte SQL-92 lié à ma réponse sur DBA.SE : dba.stackexchange.com/questions/2511/

12voto

Richard Points 54016

Je m'attendrais à ce que l'optimiseur s'assure qu'il n'y a pas de différence réelle en dehors des cas limites bizarres.

Comme pour toute chose, la seule façon de le savoir est de mesurer vos cas spécifiques.

Cela dit, j'ai toujours utilisé COUNT(*) .

0 votes

Selon la réponse acceptée, ce n'est pas vrai pour MS SQL - il n'y a en fait aucune différence entre les deux.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X