sql >> Base de Datos >  >> RDS >> Sqlserver

Count(*) vs Count(Id) en el servidor sql 2005

Thilo clavó la diferencia con precisión... COUNT( column_name ) puede devolver un número menor que COUNT( * ) si column_name puede ser NULL .

Sin embargo, si puedo tomar un ángulo ligeramente diferente al responder a su pregunta, ya que parece que se está enfocando en el rendimiento.

Primero, tenga en cuenta que emitir SELECT COUNT(*) FROM table; potencialmente bloqueará a los escritores, y también será bloqueado por otros lectores/escritores a menos que haya alterado el nivel de aislamiento (el reflejo tiende a ser WITH (NOLOCK) pero veo un número prometedor de personas que finalmente comienzan a creer en RCSI). Lo que significa que mientras lee los datos para obtener su recuento "preciso", todas estas solicitudes de DML se acumulan, y cuando finalmente libera todos sus bloqueos, se abren las compuertas, un montón de insertar/actualizar/eliminar sucede la actividad, y ahí va tu cuenta "precisa".

Si necesita un recuento de filas absolutamente preciso y coherente desde el punto de vista transaccional (incluso si solo es válido para la cantidad de milisegundos que se tarda en devolverle el número), entonces SELECT COUNT( * ) es tu única opción.

Por otro lado, si está tratando de obtener una precisión aproximada del 99,9 %, estará mucho mejor con una consulta como esta:

SELECT row_count = SUM(row_count)
  FROM sys.dm_db_partition_stats
  WHERE [object_id] = OBJECT_ID('dbo.Table')
  AND index_id IN (0,1);

(La SUM está ahí para dar cuenta de las tablas particionadas; si no está utilizando la partición de tablas, puede omitirla).

Este DMV mantiene recuentos de filas precisos para las tablas, con la excepción de las filas que actualmente participan en transacciones, y esas mismas transacciones son las que harán que su SELECT COUNT espera de consulta (y, en última instancia, hacerlo inexacto antes de que tenga tiempo de leerlo). Pero de lo contrario, esto conducirá a una respuesta mucho más rápida que la consulta que propone, y no menos precisa que usar WITH (NOLOCK) .