Pregunta Count (*) vs Count (1) - Servidor SQL


Me preguntaba si alguno de ustedes usa Count(1) encima Count(*) y si hay una diferencia notable en el rendimiento o si este es solo un hábito heredado que se ha presentado desde tiempos pasados?

(La base de datos específica es SQL Server 2005.)


610
2017-08-03 10:15


origen


Respuestas:


No hay diferencia.

Razón:

Libros en línea dice "COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )"

"1" es una expresión no nula: por lo tanto, es lo mismo que COUNT(*). El optimizador lo reconoce por lo que es: trivial.

Lo mismo 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

Mismo IO, mismo plan, las obras

Edit, ago 2011

Pregunta similar en DBA.SE.

Editar, dic 2011

COUNT(*) se menciona específicamente en ANSI-92 (buscar "Scalar expressions 125")

Caso:

a) Si se especifica COUNT (*), entonces el resultado es la cardinalidad de T.

Es decir, el estándar ANSI lo reconoce como sangrado obvio a lo que se refiere. COUNT(1) ha sido optimizado por vendedores de RDBMS porque de esta superstición De lo contrario, se evaluaría según ANSI

b) De lo contrario, deje que TX sea la tabla de columna única que es la                 resultado de aplicar la <value expression> a cada fila de T                 y eliminando valores nulos. Si uno o más valores nulos son                 eliminado, entonces se plantea una condición de finalización: advertencia-


516
2017-08-03 10:36



En SQL Server, estas declaraciones producen los mismos planes.

Al contrario de la opinión popular, en Oracle también lo hacen.

SYS_GUID() en Oracle es bastante función de cálculo intensivo.

En mi base de datos de prueba, t_even es una mesa con 1,000,000 filas

Esta consulta:

SELECT  COUNT(SYS_GUID())
FROM    t_even

corre por 48 segundos, ya que la función necesita evaluar cada SYS_GUID() regresó para asegurarse de que no es un NULL.

Sin embargo, esta consulta:

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

corre por mas 2 segundos, ya que ni siquiera intenta evaluar SYS_GUID() (A pesar de * siendo un argumento para COUNT(*))


64
2017-08-03 10:34



Claramente, COUNT (*) y COUNT (1) siempre devuelve el mismo resultado Por lo tanto, si uno fuera más lento que el otro, sería efectivamente debido a un error del optimizador. Como ambos formularios se utilizan con mucha frecuencia en las consultas, no tendría sentido que un DBMS permitiera que dicho error permanezca sin corregir. Por lo tanto, encontrará que el rendimiento de ambas formas es (probablemente) idéntico en todos los principales DBMS de SQL.


49
2017-08-03 10:45



En el estándar SQL-92, COUNT(*) específicamente significa "la cardinalidad de la expresión de la tabla" (podría ser una tabla base, `VER, tabla derivada, CTE, etc.).

Creo que la idea era que COUNT(*) es fácil de analizar. El uso de cualquier otra expresión requiere que el analizador se asegure de que no haga referencia a ninguna columna (COUNT('a') dónde a es un literal y COUNT(a) dónde a es una columna puede arrojar resultados diferentes).

En la misma vena, COUNT(*) puede ser elegido fácilmente por un codificador humano familiarizado con los Estándares SQL, una habilidad útil cuando se trabaja con más de una oferta de SQL de un proveedor.

Además, en el caso especial SELECT COUNT(*) FROM MyPersistedTable;, el pensamiento es que el DBMS es probable que contenga estadísticas para la cardinalidad de la tabla.

Por lo tanto, porque COUNT(1) y COUNT(*) son semánticamente equivalentes, yo uso COUNT(*).


18
2018-05-13 10:36



COUNT(*) y COUNT(1) son iguales en caso de resultado y rendimiento.


15
2017-08-03 13:10



Esperaría que el optimizador se asegure de que no haya diferencia real fuera de los casos de bordes extraños.

Como con cualquier cosa, la única forma real de decir es medir sus casos específicos.

Dicho eso, siempre he usado COUNT(*).


12
2017-08-03 10:17



Ejecuté una prueba rápida en SQL Server 2012 en un cuadro hiperv de RAM de 8 GB. Puedes ver los resultados por ti mismo. No estaba ejecutando ninguna otra aplicación de ventana aparte de SQL Server Management Studio mientras ejecutaba estas pruebas.

Mi esquema de tabla:

CREATE TABLE [dbo].[employee](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_employee] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Número total de registros en Employee tabla: 178090131 (~ 178 millones de filas)

Primera consulta:

Set Statistics Time On
Go    
Select Count(*) From Employee
Go    
Set Statistics Time Off
Go

Resultado de la primera consulta:

 SQL Server parse and compile time: 
 CPU time = 0 ms, elapsed time = 35 ms.

 (1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 10766 ms,  elapsed time = 70265 ms.
 SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Segunda consulta:

    Set Statistics Time On
    Go    
    Select Count(1) From Employee
    Go    
    Set Statistics Time Off
    Go

Resultado de la segunda consulta:

 SQL Server parse and compile time: 
   CPU time = 14 ms, elapsed time = 14 ms.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 11031 ms,  elapsed time = 70182 ms.
 SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

Puede observar que hay una diferencia de 83 (= 70265 - 70182) milisegundos que se puede atribuir fácilmente a la condición exacta del sistema en el momento en que se ejecutan las consultas. También hice una sola carrera, por lo que esta diferencia será más precisa si hago varias ejecuciones y hago algún promedio. Si para un conjunto de datos tan grande la diferencia llega a menos de 100 milisegundos, entonces podemos concluir fácilmente que las dos consultas no tienen ninguna diferencia de rendimiento exhibida por el Motor SQL Server.

Nota : RAM alcanza casi el 100% de uso en ambas carreras. Reinicié el servicio de SQL Server antes de iniciar ambas ejecuciones.


7
2017-08-20 03:54



SET STATISTICS TIME ON

select count(1) from MyTable (nolock) -- table containing 1 million records. 

Tiempos de ejecución de SQL Server:
  Tiempo de CPU = 31 ms, tiempo transcurrido = 36 ms.

select count(*) from MyTable (nolock) -- table containing 1 million records. 

Tiempos de ejecución de SQL Server:
  Tiempo de CPU = 46 ms, tiempo transcurrido = 37 ms.

Lo he ejecutado cientos de veces, borrando el caché cada vez .. Los resultados varían de vez en cuando ya que la carga del servidor varía, pero casi siempre cuenta (*) tiene un tiempo de CPU más alto.


7
2018-02-04 02:27



Como esta pregunta surge una y otra vez, aquí hay una respuesta más. Espero agregar algo para principiantes preguntándome acerca de las "mejores prácticas" aquí.

SELECT COUNT(*) FROM something cuenta registros, que es una tarea fácil.

SELECT COUNT(1) FROM something recupera un 1 por registro y que cuenta los 1s que no son nulos, que es esencialmente registros de conteo, solo que más complicado.

Habiendo dicho esto: Good dbms nota que la segunda declaración dará como resultado la misma cuenta que la primera y la reinterpretará en consecuencia, para no hacer un trabajo innecesario. Por lo general, ambas declaraciones darán como resultado el mismo plan de ejecución y tomarán la misma cantidad de tiempo.

Sin embargo, desde el punto de lectura, debe usar la primera declaración. Desea contar los registros, así que cuente los registros, no las expresiones. Use COUNT (expresión) solo cuando desee contar las ocurrencias no nulas de algo.


6
2018-05-05 10:43