Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Conteggio(*) vs Conteggio(Id) in SQL Server 2005

Thilo ha individuato la differenza con precisione... COUNT( column_name ) può restituire un numero inferiore a COUNT( * ) se column_name può essere NULL .

Tuttavia, se posso rispondere alla tua domanda da un punto di vista leggermente diverso, dal momento che sembri concentrarti sulle prestazioni.

Innanzitutto, nota che emettendo SELECT COUNT(*) FROM table; bloccherà potenzialmente gli scrittori e sarà anche bloccato da altri lettori/scrittori a meno che tu non abbia alterato il livello di isolamento (l'effetto a scatti tende ad essere WITH (NOLOCK) ma vedo un numero promettente di persone che finalmente iniziano a credere in RCSI). Ciò significa che mentre leggi i dati per ottenere il tuo conteggio "accurato", tutte queste richieste DML si stanno accumulando e quando hai finalmente rilasciato tutti i tuoi blocchi, le porte si aprono, un mucchio di inserimenti/aggiornamenti/eliminazioni si verifica l'attività e il conteggio "preciso".

Se hai bisogno di un conteggio delle righe assolutamente coerente e accurato dal punto di vista transazionale (anche se è valido solo per il numero di millisecondi necessari per restituirti il ​​numero), allora SELECT COUNT( * ) è la tua unica scelta.

D'altra parte, se stai cercando di ottenere un campo di gioco accurato al 99,9%, stai molto meglio con una query come questa:

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 è lì per tenere conto delle tabelle partizionate:se non stai utilizzando il partizionamento delle tabelle, puoi ometterlo.)

Questo DMV mantiene conteggi accurati delle righe per le tabelle ad eccezione delle righe che stanno attualmente partecipando alle transazioni - e quelle stesse transazioni saranno quelle che renderanno il tuo SELECT COUNT query wait (e alla fine rendilo impreciso prima di avere il tempo di leggerlo). Ma altrimenti questo porterà a una risposta molto più rapida rispetto alla domanda che proponi e non meno accurata dell'utilizzo di WITH (NOLOCK) .