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:
-
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. -
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
Danke Sascha, genau sowas suchte ich
Moin und danke für den Tipp mit sysindexes.
Aber: Wie verfahre ich, wenn ich es nicht mit einer Tabelle, sondern mit einem View zu tun habe? Komm ich hier irgendwie um einen Table-Scan herum?
Grüße!
Hallo Hendrik!
Bei Views wirst Du wahrscheinlich nicht um eine Art Table-Scan drum rum kommen (Je nachdem was Du in den Views machst).
Ggf. wären Indexed Views eine Option.
Ich schau mir das aber mal im Detail an und meld mich dann nochmal bei Dir.
Viele Grüße,
Sascha
Vielen Dank!