posted 5/23/2012 by pkumar3 - Views: [719]
Ever needed to calculate the number of rows inserted every second, for every table in every database on a server? Or, have you ever needed to validate that all processes have stopped writing to tables? These types of questions come up routinely for me. To help with this, I’ve written the following script, which examines metadata values using sys.partitions. This method isn’t as accurate as running SELECT COUNT(*) FROM, but it’s much faster. Keep in mind, since it’s just looking at row counts, it’s not much help on tables that have a lot of update/delete activity. But it does what I need it to do, and I use it pretty regularly, so I thought I’d share in case anyone else can benefit from it too.
/* Declare Parameters */ DECLARE @newBaseline BIT = 1 -- change to 0 when you don't want to replace the baseline, i.e. after initial run , @delay CHAR(8) = '00:00:30'; -- change as needed IF @newBaseline = 1 BEGIN IF OBJECT_ID('tempdb..#baseline') IS NOT NULL DROP TABLE #baseline; CREATE TABLE #baseline ( database_name SYSNAME , table_name SYSNAME , table_rows BIGINT , captureTime DATETIME NULL ); END IF OBJECT_ID('tempdb..#current') IS NOT NULL DROP TABLE #current; CREATE TABLE #current ( database_name SYSNAME , table_name SYSNAME , table_rows BIGINT , captureTime DATETIME NULL ); IF @newBaseline = 1 BEGIN EXECUTE sp_MSforeachdb 'USE ?; INSERT INTO #baseline SELECT DB_NAME() , o.name As [tableName] , SUM(p.[rows]) As [rowCnt] , GETDATE() As [captureTime] FROM sys.indexes As i JOIN sys.partitions As p ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id JOIN sys.objects As o ON i.[object_id] = o.[object_id] WHERE i.[type] = 1 GROUP BY o.name;' WAITFOR DELAY @delay; END EXECUTE sp_MSforeachdb 'USE ?; INSERT INTO #current SELECT DB_NAME() , o.name As [tableName] , SUM(p.[rows]) As [rowCnt] , GETDATE() As [captureTime] FROM sys.indexes As i JOIN sys.partitions As p ON i.[object_id] = p.[object_id] AND i.index_id = p.index_id JOIN sys.objects As o ON i.[object_id] = o.[object_id] WHERE i.[type] = 1 GROUP BY o.name;' SELECT c.* , c.table_rows - b.table_rows AS 'new_rows' , DATEDIFF(second, b.captureTime, c.captureTime) AS 'time_diff' , (c.table_rows - b.table_rows) / DATEDIFF(second, b.captureTime, c.captureTime) AS 'rows_per_sec' FROM #baseline AS b JOIN #current AS c ON b.table_name = c.table_name AND b.database_name = c.database_name ORDER BY new_rows DESC;