¿Cuál es la diferencia entre select count (*) y select count (any_non_null_column)?

58

Me parece recordar que (en Oracle) hay una diferencia entre pronunciar select count(*) from any_tabley select count(any_non_null_column) from any_table.

¿Cuáles son las diferencias entre estas dos declaraciones, si las hay?

Martín
fuente

Respuestas:

72
  • COUNT (*) incluirá NULLS
  • COUNT (column_or_expression) no lo hará.

Esto significa COUNT(any_non_null_column)que dará lo mismo que, COUNT(*)por supuesto, porque no hay valores NULL para causar diferencias.

En general, COUNT(*)debería ser mejor porque se puede usar cualquier índice porque COUNT(column_or_expression)no se puede indexar o SARGable

De ANSI-92 (busque " Scalar expressions 125")

Caso:

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

b) De lo contrario, deje que TX sea la tabla de una sola columna que es el resultado de aplicar la <expresión de valor> a cada fila de T y eliminar los valores nulos. Si se eliminan uno o más valores nulos, se genera una condición de finalización: advertencia: se elimina el valor nulo en la función establecida.

Las mismas reglas se aplican a SQL Server y Sybase también al menos

Nota: COUNT (1) es lo mismo que COUNT (*) porque 1 es una expresión no anulable.

gbn
fuente
44
Solo para completar: Oracle usará un escaneo de índice en una columna indexada no nula si count(*)se usa.
a_horse_with_no_name
Pensé que las tres opciones posibles eran COUNT(*), COUNT(<constant>)y COUNT(<column name>)que las tres podrían tener el prefijo ALLo DISTINCT(por defecto ALLsi se omite). Me pregunto qué expresión se puede usar donde dices _or_expression.
cuando el
2
@onedaywhen COUNT(1)como un ejemplo inútil, es lo mismo que COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)como un ejemplo que cuenta filas donde a> b.
ypercubeᵀᴹ
16

En cualquier versión reciente (es decir, 8.x + ) de Oracle, hacen lo mismo . En otras palabras, la única diferencia es semántica:

select count(*) from any_table

es fácilmente legible y obvio lo que está tratando de hacer, y

select count(any_non_null_column) from any_table

es más difícil de leer porque

  1. es mas largo
  2. es menos reconocible
  3. tienes que pensar si any_non_null_columnrealmente se aplica comonot null

En resumen, usecount(*)

Jack Douglas
fuente
9

En una versión reciente, de hecho, no hay diferencia entre count (*) y count ( cualquier columna no nula ), con el énfasis en not null :-) Incidentalmente cubrí ese tema con una publicación de blog: ¿Es count (col) mejor que count (*)?

Uwe Hesse
fuente
1

En el libro Oracle8i Certified Professional DBA Certification Exam Guide (ISBN 0072130601) , la página 78 dice que COUNT (1) en realidad se ejecutará más rápido que COUNT (*) porque se ponen en juego ciertos mecanismos para verificar el diccionario de datos para la nulabilidad de cada columna (o al menos la primera columna con no anulabilidad) cuando se usa COUNT (*) . COUNT (1) evita esos mecanismos.

MySQL hace trampa para 'SELECT COUNT (1) en tblname;' en las tablas MyISAM leyendo el encabezado de la tabla para el recuento de tablas. InnoDB cuenta cada vez.

Para probar si COUNT (1) se ejecutará más rápido que COUNT (*) en una forma independiente de la base de datos, simplemente ejecute lo siguiente y juzgue el tiempo de ejecución por usted mismo:

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

Esto hace que la función COUNT opere en el mismo campo de juego, independientemente del motor de almacenamiento o RDBMS.

RolandoMySQLDBA
fuente
8
La guía del examen está mal. En Oracle count (*) = count (1) (al menos después de la versión 7). Ver asktom.oracle.com/pls/asktom/… (ya referenciado por @JackPDouglas)
Leigh Riffel
3
Interesante. COUNT (*) no debe verificar columnas en absoluto según las especificaciones ANSI. Me preguntaron en SO para SQL Server hace algún tiempo también stackoverflow.com/questions/1221559/count-vs-count1/…
gbn
@gbn, @Leigh Riffel, @bernd_k Gracias por intervenir y recordarme que lea y aprenda más, especialmente porque no he estado trabajando con Oracle por un tiempo.
RolandoMySQLDBA