Showing posts with label sp_MSforeachtable. Show all posts
Showing posts with label sp_MSforeachtable. Show all posts

August 23, 2010

SQL SERVER: Display Row count of all the tables

Recently we have performance issue in SQL SERVER and we decided to move some large tables to different file group, so we can improve SQL SERVER performance, as it uses other disks I/O. Now challenge is to identify large tables from many tables (approx 700 tables).

There are few ways to display row count of all the tables:
  1. Use Procedure: sp_msForEachTable (Simplest way)

  2. Read information from system tables ( approximate count, Preffered)

Let me explain both of the method:

1. Use Procedure: sp_msForEachTable:

This is the simplest way that we can make COUNT(*) to each table to find number of rows from each table. This is undocumented stored procedure,"sp_msForEachTable" gives ability to make a query to all tables.
EXEC sp_msForEachTable 'SELECT ''?'' AS TableName,COUNT(*) AS NoOfRows FROM ?'

Its nothing but just a simple dynamic SQL statement where "?" will be replaced by table name. So query will be like:
SELECT COUNT(*) FROM BuildVersion


This procedure, "sp_msForEachTable", will loop to each table for current database and count rows from each table. So it gives result like:



By this way, we can get row count from all the tables for current database. But question is: How to use this result set? How to find out which table has maximum rows? To find out this, I need to check each table's rows manually and then only I can find out which table has maximum rows. This is time consuming and not the good way to find out table with maximum rows. Let see another method on which we can find it out it easily.

2. Read information from system tables:

By reading system tables, we can also find out rows from each table. We can use following query to find out number of rows from each table.
SELECT 
 st.Name AS TableName,
 SUM(  
  CASE  
   WHEN (p.index_id < 2) AND (a.type = 1) THEN p.rows  
   ELSE 0  
  END  
 ) AS NoOfRows
FROM sys.partitions p
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN sys.tables st ON st.object_id = p.Object_ID
INNER JOIN sys.schemas sch ON sch.schema_id = st.schema_id
GROUP BY st.name

NOTE: This method is used to get an *approximate* count for all tables.

This query solved my purpose. In this query, it will give result in single result set, so we can manipulate it easily.



E.g. List out all tables and sort it out based on the NumberOfRows.
So, my query will be:
SELECT 
 st.Name AS TableName,
 SUM(  
  CASE  
   WHEN (p.index_id < 2) AND (a.type = 1) THEN p.rows  
   ELSE 0  
  END  
 ) AS NoOfRows
FROM sys.partitions p
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN sys.tables st ON st.object_id = p.Object_ID
INNER JOIN sys.schemas sch ON sch.schema_id = st.schema_id
GROUP BY st.name
ORDER BY NoOfRows DESC


Let me know your opinions.

April 26, 2009

SQL SERVER - Query to compare number of Rows between different Databases



We have two databases in the same SQL server instance. Both of the databases are copy of the production database, so both contains same tables. We added some records in Test Database’s some tables to update some features. We have added data in many tables of test database. Now we need to also update Production DB with the updated data. To update Production Database, we need to make sure in which tables we have updated data and then we will check and update production database accordingly. We have many numbers of tables, and we have updated many tables, so its not possible for us to check it manually.

So, we need to make query to compare rows of each table with the another database tables, to find out which tables has different rows then the original database.

Solution:

As I need to solve this problem, I write a query which will give me Rows of each table in one Database. As I need to compare it with another database I write the following query to come out with the solution. 
Example:

I have two databases. Database A and Database B.

I need to make a report, which will give me details of each table and rows.

I made this Stored Procedure in Database A.

CREATE PROC CompareRowsBetweenDatabas
AS
WITH A AS(
SELECT
sch.name AS SchemaName,
st.Name AS TableName,
SUM(
CASE
WHEN (p.index_id < 2) AND (a.type = 1) THEN p.rows
ELSE 0
END
) AS Rows
FROM sys.partitions p
INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN sys.tables st ON st.object_id = p.Object_ID
INNER JOIN sys.schemas sch ON sch.schema_id = st.schema_id
GROUP BY st.name, sch.name

),
b as(
SELECT
sch.name AS SchemaName,
st.Name AS TableName,
SUM(
CASE
WHEN (p.index_id < 2) AND (a.type = 1) THEN p.rows
ELSE 0
END
) AS Rows
FROM B.sys.partitions p
INNER JOIN B.sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN B.sys.tables st ON st.object_id = p.Object_ID
INNER JOIN B.sys.schemas sch ON sch.schema_id = st.schema_id
GROUP BY st.name, sch.name
)
SELECT a.SchemaName, a.TableName, a.Rows,
b.SchemaName As BSchemaName, b.TableName AS BTableName, B.Rows AS BRows
FROM a
INNER JOIN b ON a.TableName = b.TableName
AND a.SchemaName = b.SchemaName

EXEC CompareRowsBetweenDatabase




This will give me results as I need.


Let me know if it helps you.




March 26, 2009

SQL SERVER: How much space occupied by Each Table with sp_MSforeachtable procedure

Today, I came across requirement where I need to perform an action on all of the tables within a database.

For example, How much space occupied by each table.

I found undocumented Procedure: sp_MSforEachTable in the master database.

The following script reports the space used and allocated for every table in the database.

USE AdventureWorks;
EXECUTE sp_MSforeachtable 'sp_spaceused [?]'

So, We can use sp_MSforeachtable procedure when we need to loop through each table.

Let me know if it helps you in any way.