Бывает необходимость узнать размер каждой таблицы, например для создания схемы секционирования. В этом нам поможет процедура sp_spaceused:
DBCC UPDATEUSAGE (0); CREATE TABLE #t([имя таблицы] varchar(255), [строк] varchar(255), [зарезервировано] varchar(255), [всего данных] varchar(255), [размер индексов] varchar(255), [свободно] varchar(255)); INSERT INTO #t exec sp_msforeachtable N'exec sp_spaceused ''?'''; SELECT * FROM #t ORDER BY CONVERT(bigint, REPLACE([всего данных], ' KB', '')) DESC; DROP TABLE #t;
Команда DBCC UPDATEUSAGE (0); вызывается для более точного определения занимаемого пространства.
Данный запрос выполняется достаточно долго, но при этом большой нагрузки на сервер не создаёт.
Предыдущий способ не является оптимальным. Следующий скрипт выполняется значительно быстрее:
DECLARE @pagesizeKB INT SELECT @pagesizeKB = low / 1024 FROM master.dbo.spt_values WHERE NUMBER = 1 AND TYPE = 'E' SELECT TABLE_NAME = OBJECT_NAME(o.id), ROWS = i1.rowcnt, reservedMB = (ISNULL(SUM(i1.reserved), 0) + ISNULL(SUM(i2.reserved), 0)) * @pagesizeKB/1024, dataMB = (ISNULL(SUM(i1.dpages), 0) + ISNULL(SUM(i2.used), 0)) * @pagesizeKB/1024, index_sizeMB = ((ISNULL(SUM(i1.used), 0) + ISNULL(SUM(i2.used), 0)) - (ISNULL(SUM(i1.dpages), 0) + ISNULL(SUM(i2.used), 0))) * @pagesizeKB/1024, unusedMB = ((ISNULL(SUM(i1.reserved), 0) + ISNULL(SUM(i2.reserved), 0)) - (ISNULL(SUM(i1.used), 0) + ISNULL(SUM(i2.used), 0))) * @pagesizeKB/1024 FROM sysobjects o LEFT OUTER JOIN sysindexes i1 ON i1.id = o.id AND i1.indid < 2 LEFT OUTER JOIN sysindexes i2 ON i2.id = o.id AND i2.indid = 255 WHERE OBJECTPROPERTY(o.id, N'IsUserTable') = 1 --same as: o.xtype = 'IsView' OR (OBJECTPROPERTY(o.id, N'IsView') = 1 AND OBJECTPROPERTY(o.id, N'IsIndexed') = 1) GROUP BY o.id, i1.rowcnt ORDER BY dataMB DESC