I have a scenario where every user has been allocated 2 MB of database space. Now I have to show Percenatge usage of their allocated space, to do so I need to know the size of s
You can calculate the size a row (of number of rows) with a fairly complex formula. See Books Online (ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/81fd5ec9-ce0f-4c2c-8ba0-6c483cea6c75.htm) for the exact details.
In short:
Take the number of columns and determine the size of each column by its datatype for fixed-length datatypes.
Calculate the space used for any nullable columns Then calculate the rowspace:
Row_Size = Fixed_Data_Size + Variable_Data_Size + Null_Bitmap + 4
The following query will tell you the percentage of @SpaceAllotted that is being used by the data by looking at how many pages are allocated by the database's objects.
It's not worth attempting to measure usage at the row-level, since SQL Server allocates all space at the extent-level. Each extent is composed of eight 8KB data pages. So if your database only had one row, and that row had 4 bytes of data, an entire extent would still need to be allocated to hold that 4 bytes (or an existing extent with unallocated pages would be used. This is called a mixed extent).
DECLARE @SpaceAllotted FLOAT
-- 2MB converted to kilobytes...
SET @SpaceAllotted = 2048
SELECT
-- Allocation is done on the extent-level.
-- Each extent contains eight 8KB data pages.
((1 / (@SpaceAllotted)) * CEILING(CAST(SUM([ips].[page_count]) AS FLOAT) / 8) * 64) * 100 AS PercentageUsed
FROM
[sys].[dm_db_index_physical_stats](DB_ID(), NULL, NULL, NULL, NULL) ips
-- This will allow us to retrieve the page count of all tables in the
-- current database, regardless of whether or not they have clustered
-- indexes and/or non-clustered indexes.
INNER JOIN
[sys].[indexes] i
ON
[ips].[object_id] = [i].[object_id]
AND [ips].[index_id] = [i].[index_id]
Since we do have the possibility of mixed extents, and no good way (there are ways, but they're not going to be pretty) of determining what pages are allocated to what extents, this isn't 100% accurate. Additionally, extents may even have free pages (that are reserved and therefore still taking up disk space), so generally, this estimate will always come in low. However, it's probably the best you're going to get without writing something to inspect the database at the page-level.
Ah yes, looking at the other answers, this is another option. This will basically look at all the current size of the data files in pages, and determine the percentage of the space they have consumed. Now, there are caveats here as well...
Hope one of these solves your problem.
SELECT
((1 / CAST(SUM([df].[max_size]) AS FLOAT)) * CAST(SUM([df].[size]) AS FLOAT)) * 100 AS PercentUsed
FROM
[sys].dm_io_virtual_file_stats(DB_ID(), NULL) vfs
INNER JOIN
[sys].[database_files] df
ON
[vfs].[file_id] = [df].[file_id]
WHERE
[df].[type] = 0
Run DBCC SHOWCONTIG with your table name
dbcc showcontig ('TableName') with tableresults
then look at max min and average record size
Since showcontig is going to be deprecated, you can also use:
SELECT * FROM sys.dm_db_index_physical_stats
(DB_ID(N'DatabaseName'), OBJECT_ID(N'TableName'), NULL, NULL , 'DETAILED')
The data is saved on disk in directories named for the database. That includes everything, including what you're not measuring (indices, etc.). Measure that.