Anzahl der Tabellenzeilen schnell und einfach abfragen

Der klassische Ansatz

Die Fragestellung “Wie viele Zeilen hat diese Tabelle” taucht wohl bei jedem Entwickler immer mal wieder auf.

Die Standardantwort lautet dann:

SELECT COUNT(*)
FROM [dbo].[Tabelle]

Allerdings können hierbei zwei Probleme auftreten:

  1. Der SQL Server muss zum Bearbeiten dieser Abfrage einen Table-Scan durchführen. Das kann bei Tabellen mit mehreren Millionen Datensätzen eine Weile dauern.
  2. Man kann mit dieser Abfrage nur jeweils eine Tabelle gleichzeitig abfragen. Was macht man aber, wenn man die Zeilenanzahl aller Tabellen einer Datenbank bestimmen möchte?

Um das erste Problem zu lösen, kann man die Gespeicherte Prozedur sp_spaceused verwenden.
Ohne Parameter ausgeführt, zeigt diese den Speicherverbrauch der aktuellen Datenbank an.
Mit einem Tabellennamen als Parameter, wird der Speicherverbrauch der Tabelle inkl. Zeilenanzahl zurückgegeben.

Um das zweite Problem zu lösen, muss man mittels Curserprogrammierung jede Tabelle einzeln abfragen oder die undokumentierte Gespeicherte Prozedur sp_MSforeachtable verwenden.

Alternativ kann man mit folgenden Abfragen die beiden Probleme lösen:

Abfrage mit Hilfe der sysindexes

Wenn der SQL 2000 verwendet wird, muss die Abfrage wie folgt aussehen:

-- Zeigt alle Benutzertabellen mit zugehöriger Zeilenanzahl
-- i.indid < 2 filtert nach "clustered index" (1) und "hash table" (0).
-- Entfernen Sie den "OBJECTPROPERTY(o.id, 'IsMSShipped') = 0" filter,
-- um Systemtabellen anzuzeigen
SELECT o.name, i.rowcnt
FROM sysindexes AS i
INNER JOIN sysobjects AS o
ON  i.id = o.id
WHERE i.indid < 2
AND OBJECTPROPERTY(o.id, 'IsMSShipped') = 0
ORDER BY o.name

Abfrage mit Hilfe der DMVs

Beim SQL 2005 / 2008 kann die Abfrage, mit Hilfe der DMVs, wie folgt aussehen:

-- Zeigt alle Benutzertabellen mit zugehöriger Zeilenanzahl
-- i.index_id < 2 filtert nach "clustered index" (1) und "hash table" (0).
-- Entfernen Sie den is_ms_shipped = 0 filter, um Systemtabellen anzuzeigen
SELECT o.name, ddps.row_count
FROM sys.indexes AS i
INNER JOIN sys.objects AS o
ON i.OBJECT_ID = o.OBJECT_ID
INNER JOIN sys.dm_db_partition_stats AS ddps
ON i.OBJECT_ID = ddps.OBJECT_ID
AND i.index_id = ddps.index_id
WHERE i.index_id < 2
AND o.is_ms_shipped = 0
ORDER BY o.name
SQL Server Closeup #1: Strukturen zur Speicherung von Daten – Records
SQL Server Closeup #2: Strukturen zur Speicherung von Daten – Pages

Was denkst Du darüber?