Veritabanındaki tüm tabloların boyutunu alma


1271

Oldukça büyük bir SQL Server veritabanını miras aldım. İçerdiği veriler göz önüne alındığında, beklediğimden daha fazla yer kaplıyor gibi görünüyor.

Her tablonun diskte ne kadar yer harcadığını belirlemenin kolay bir yolu var mı?


hangi rollere erişiminiz var? DBA siz misiniz, yoksa bu bir web barındırıcısı, istemci veya benzeri aracılığıyla mı yönetiliyor?
Rob Allen


@RobAllen Veritabanına tam erişimim var, bu yüzden herhangi bir rol gerektiren bir komut dosyası yeterli.
Eric


Azure için kullandığım bu
IRF

Yanıtlar:


2593
SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    CAST(ROUND(((SUM(a.total_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS TotalSpaceMB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    CAST(ROUND(((SUM(a.used_pages) * 8) / 1024.00), 2) AS NUMERIC(36, 2)) AS UsedSpaceMB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB,
    CAST(ROUND(((SUM(a.total_pages) - SUM(a.used_pages)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255 
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    TotalSpaceMB DESC, t.Name

7
Aptalca bir soru, ancak bu sorgunun satır kilitlemesine neden olması mümkün mü?
GEMI

7
Dizinler de boşluk kullanır ve dizinler tarafından kullanılan miktar alanı aşağıdaki bu sorgu ile bulunabilir .
Jens Frandsen

6
Komut dosyanızın filtrelenmiş dizinlerle ilgili sorunları var: Belirli bir tablo için filtrelenen her dizin için sonuçlarda bu tabloların adıyla fazladan bir satır görüyorum. Bu ekstra satırların her birinin "RowCounts" değeri, filtrelenmiş dizinlerden birinin kapsadığı satır sayısına karşılık gelir. (Sql2012'de)
Akos Lukacs

37
@Todd: bazı insanlar bu şekilde sipariş edilmesini istiyor - diğerleri tablo adına göre istiyor - seçiminizi yapın, kodu gerektiği gibi uyarlayın ....
marc_s

12
Tablolarınız bölümlenmişse, neler olup bittiğine dair herhangi bir gösterge olmadan birden çok kez görünür. Seçim listesine p.partition_number ekleyebilir veya TOPLA (p.Rows) ve grubundan tarafından kaldırabilirsiniz.
PRMan

561

Eğer kullanıyorsanız , SQL Server Management Studio'yu (SSMS) yerine (Sorgu çalıştırmanın benim durumumda yinelenen satırları iade ) Bir çalıştırabilirsiniz standart raporu

  1. Veritabanına sağ tıklayın
  2. Raporlar> Standart Raporlar> Tabloya Göre Disk Kullanımı'na gidin

Not: Bunun doğru çalışması için veritabanı uyumluluk düzeyi 90 veya üstü olarak ayarlanmalıdır. Bkz. Http://msdn.microsoft.com/en-gb/library/bb510680.aspx


54
Management Studio 2012'de şunları yapabilirsiniz: Görünüm-Nesne Gezgini Ayrıntıları (F7) ve Nesne Gezgini'nde "Tablolar" a gidin. Ayrıntılar'da başlığa sağ tıklayın ve boyut sütunlarını seçin.
ValGe

3
SSMS 2012 ile yeni işlevsellik önermek için. Biz eski meraklıları için, biz hiç mevcut değildi. Biz de eski TSQL yolunu
yaptık

3
İster inanın ister inanmayın, bazen sadece ölümlüler (geliştiriciler) bu bilgileri görmek ister ve yerleşik raporu kullanma iznimiz yoktur, ancak TSQL'i kabul edilen cevapta çalıştırabiliriz. :) FYI (BTW, hala cevabını iptal ettim)
Andrew

8
Azure SQL'de mevcut görünmüyor :-(
Simon_Weaver

1
Bunun ciddi olmadığını biliyorum, ama, lütfen, marjinalleşmiş grupları mühendislik ve teknolojiden uzaklaştırıyorsunuz ve bu akıl yürütme her yerde tekrarlanıyor. Her ikisini de öğrenmelisiniz, ancak insanları daha akıllıca ve daha hızlı çalışmak için zaman kazandıran yardımcı programları kullandıkları için zorlamamalısınız. (SSMS bazen "yavaşlayan bir yardımcı program" gibi görünse de ...: X) Microsoft tarafından oluşturulan araçlar, kullanıcı arayüzü ile ilgili her şey için istisna olma eğiliminde olsa da, sekmeli veri okumaları genellikle bir GUI'de daha açıktır.
Julia McGuigan

102

sp_spaceused, tablo, dizinlenmiş görünüm veya tüm veritabanı tarafından kullanılan disk alanı hakkında bilgi alabilir.

Örneğin:

USE MyDatabase; GO

EXEC sp_spaceused N'User.ContactInfo'; GO

Bu, ContactInfo tablosu için disk kullanım bilgilerini bildirir.

Bunu tüm tablolarda aynı anda kullanmak için:

USE MyDatabase; GO

sp_msforeachtable 'EXEC sp_spaceused [?]' GO

Disk kullanımını SQL Server'ın sağ tıklatma Standart Raporlar işlevinden de alabilirsiniz. Bu rapora ulaşmak için, Nesne Gezgini'ndeki sunucu nesnesinden gezinin, Veritabanları nesnesine gidin ve ardından herhangi bir veritabanını sağ tıklatın. Görüntülenen menüden Raporlar'ı, ardından Standart Raporlar'ı ve ardından "Bölüme Göre Disk Kullanımı: [VeritabanıAdı]" seçeneğini belirleyin.


3
sp_msforeachtableSSMS'de kullanımı System.OutOfMemoryExceptionçok sayıda tablonuz varsa kolayca tetikleyebilir, ancak sonuçları saklamak için geçici bir tablo kullanmak daha iyi bir fikir olabilir.
syneticon-dj

1
Sp_spacedused ile görebildiğim ana sorun, verileri okunabilir biçimde döndürmek gibi görünüyor (örneğin benim durumumda 'ayrılmış' sütununda '152 KB' vardı). Bunun uygun şekilde MB / GB'ye geçeceğini varsayıyorum. Bu, birçok durumda açıkça yararlıdır, ancak büyüklüğe bağlı olarak bir mantık uygulamanız gerekiyorsa veya değerleri veya herhangi bir şeyi karşılaştırmak istiyorsanız değil. Bunu kapatmanın bir yolunu aradım, ancak birini tespit edemedim (SQL Server 2005 kullanıyorum :()
DarthPablo

55

İşte başka bir yöntem: SQL Server Management Studio'yu kullanarak , Nesne Gezgini'nde veritabanınıza gidin ve Tablolar'ı seçin

resim açıklamasını buraya girin

Sonra Nesne Gezgini Ayrıntılarını açın ( F7 tuşuna basarak veya Görünüm-> Nesne Gezgini Ayrıntıları'na gidin ). Nesne gezgini ayrıntıları sayfasında, sütun başlığına sağ tıklayın ve sayfada görmek istediğiniz sütunları etkinleştirin. Verileri herhangi bir sütuna göre de sıralayabilirsiniz.

resim açıklamasını buraya girin


Evet, Azure'daki SSMS'nin yerel sürüme kıyasla bazı özellikleri yoktur.
Serçe

@batmaci Azure SQL veritabanları hakkında yorum yaptığınızda bunun işe yarayıp yaramadığından emin değilim, ancak en azından şu anda SSMS'nin son sürümlerinde kısmen çalışıyor gibi görünüyor. Benim için tablo meta verisi sorgusu zaman aşımına uğramış gibi görünüyor, ancak yapmadan önce, seçilen tabloyu (güvenilir bir şekilde) içeren birkaç (3-10) tablo döndürüyor gibi görünüyor. Bir tablo seçin ve görüntülenmiyorsa istediğiniz tabloyu görmek için yenile'yi tıklayın.
pcdev

Azure "gerçek" SQL Server değil (ha ha)
Reversed Engineer

Kullandığım bu , Azure için bir (artı bir) ile teşekkür
IRF

NirSoft SysExporter gibi bir yardımcı program kullanarak listeyi bir CSV dosyasına da aktarabilirsiniz: nirsoft.net/utils/sysexp.html
Max

39

Bazı aramalardan sonra, tüm tablolar hakkında bilgi almak için kolay bir yol bulamadım. Veritabanı tarafından kullanılan tüm alanı döndürecek sp_spaceused adında kullanışlı bir saklı yordam vardır. Bir tablo adı verilirse, o tablonun kullandığı alanı döndürür. Ancak, sütunlar karakter değerleri olduğundan saklı yordam tarafından döndürülen sonuçlar sıralanabilir değildir.

Aşağıdaki komut dosyası aradığım bilgileri üretecek.

create table #TableSize (
    Name varchar(255),
    [rows] int,
    reserved varchar(255),
    data varchar(255),
    index_size varchar(255),
    unused varchar(255))
create table #ConvertedSizes (
    Name varchar(255),
    [rows] int,
    reservedKb int,
    dataKb int,
    reservedIndexSize int,
    reservedUnused int)

EXEC sp_MSforeachtable @command1="insert into #TableSize
EXEC sp_spaceused '?'"
insert into #ConvertedSizes (Name, [rows], reservedKb, dataKb, reservedIndexSize, reservedUnused)
select name, [rows], 
SUBSTRING(reserved, 0, LEN(reserved)-2), 
SUBSTRING(data, 0, LEN(data)-2), 
SUBSTRING(index_size, 0, LEN(index_size)-2), 
SUBSTRING(unused, 0, LEN(unused)-2)
from #TableSize

select * from #ConvertedSizes
order by reservedKb desc

drop table #TableSize
drop table #ConvertedSizes

Foreach ve SP kullanarak yukarıdaki gördükten sonra böyle bir şey yazacaktı, sevindim ben biraz zaman kurtardı görmek için aşağı kaydırdı.
Brad

37
 exec  sp_spaceused N'dbo.MyTable'

Tüm tablolar için kullanın .. (Pavlus'un yorumlarından ekleyerek)

exec sp_MSForEachTable 'exec sp_spaceused [?]'

5
Sinsi - Eğer değiştirildi exec sp_helpdbhangi etmez üzere, tablolar hakkında bir şey göstermek exec sp_spaceusedama sadece bir seferde bir tablo için ... bu size ne varsa tablolar genel bir bakış vermez ve ne kadar satır sahip oldukları ve nasıl - hangi yapar fazla yer kaplıyorlar.
marc_s

4
exec sp_MSForEachTable 'exec sp_spaceused [?]'
Paul

27

Yukarıdaki sorgular, tablo tarafından kullanılan alan miktarını bulmak için iyidir (dizinler dahil), ancak tablodaki dizinler tarafından ne kadar alan kullanıldığını karşılaştırmak istiyorsanız bu sorguyu kullanın:

SELECT
    OBJECT_NAME(i.OBJECT_ID) AS TableName,
    i.name AS IndexName,
    i.index_id AS IndexID,
    8 * SUM(a.used_pages) AS 'Indexsize(KB)'
FROM
    sys.indexes AS i
    JOIN sys.partitions AS p ON p.OBJECT_ID = i.OBJECT_ID AND p.index_id = i.index_id
    JOIN sys.allocation_units AS a ON a.container_id = p.partition_id
WHERE
    i.is_primary_key = 0 -- fix for size discrepancy
GROUP BY
    i.OBJECT_ID,
    i.index_id,
    i.name
ORDER BY
    OBJECT_NAME(i.OBJECT_ID),
    i.index_id

Belirli bir tablo için Indexsize (KB) sütununu toplamanın sp_spaceused dizininden index_size ile aynı fikirde olmama nedeni nedir?
Derek

@Derek Cevabı ekleyerek düzeltildi where [i].[is_primary_key] = 0. Şimdi boyutlar eşleşmelidir.
CodeAngry

Teşekkür ederim, ama bu aslında işe yaramıyor. Bir (çok küçük) test veritabanı var, ilgi tablosu iki dizin vardır - bir sütun birincil kümelenmiş dizin ve diğer sütun iki kümelenmemiş dizin. Bu sorgu her birinin 16kB kullandığını, ancak sp_spaceused toplam dizin kullanımının 24kB olduğunu söylüyor. Benim karışıklık bir parçasıdır: Bu sorguyu kabul edilen cevabın "UsedSpaceKB" karşılaştırıldığında, gerçek bir fark görmüyorum. Aynı katıldı, sadece sys.tables eki eksik. Bir şey eksik mi, yoksa bu sorgu doğal olarak bozuk mu?
Derek

Büyük veritabanlarım var. Ve boyutları ile eşleşir sp_spaceused. GB'leri ölçüyorum, bu yüzden birkaç megs eşleşen değil. Tam boyutları umursamıyorum, sadece bir fikir.
CodeAngry

14

SSMS'deki 'tablo özellikleri - depolama' sayfasında bulunan tam olarak aynı sayıları hesaplamanız gerekiyorsa, bunları SSMS'de yaptığınız yöntemle saymanız gerekir (sql server 2005 ve üstü için çalışır ... ve ayrıca LOB alanları olan tablolar için düzgün çalışır - çünkü yalnızca "used_pages" saymanın doğru dizin boyutunu göstermesi gerekmez):

;with cte as (
SELECT
t.name as TableName,
SUM (s.used_page_count) as used_pages_count,
SUM (CASE
            WHEN (i.index_id < 2) THEN (in_row_data_page_count + lob_used_page_count + row_overflow_used_page_count)
            ELSE lob_used_page_count + row_overflow_used_page_count
        END) as pages
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.tables AS t ON s.object_id = t.object_id
JOIN sys.indexes AS i ON i.[object_id] = t.[object_id] AND s.index_id = i.index_id
GROUP BY t.name
)
select
    cte.TableName, 
    cast((cte.pages * 8.)/1024 as decimal(10,3)) as TableSizeInMB, 
    cast(((CASE WHEN cte.used_pages_count > cte.pages 
                THEN cte.used_pages_count - cte.pages
                ELSE 0 
          END) * 8./1024) as decimal(10,3)) as IndexSizeInMB
from cte
order by 2 desc

14

MB ve GB cinsinden boyut almak için tablo bölümlerini işleyen @xav cevabı uzantısı . SQL Server 2008/2012 üzerinde test edildi (Nerede bir satır yorumladı is_memory_optimized = 1)

SELECT
    a2.name AS TableName,
    a1.rows as [RowCount],
    --(a1.reserved + ISNULL(a4.reserved,0)) * 8 AS ReservedSize_KB,
    --a1.data * 8 AS DataSize_KB,
    --(CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS IndexSize_KB,
    --(CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS UnusedSize_KB,
    CAST(ROUND(((a1.reserved + ISNULL(a4.reserved,0)) * 8) / 1024.00, 2) AS NUMERIC(36, 2)) AS ReservedSize_MB,
    CAST(ROUND(a1.data * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS DataSize_MB,
    CAST(ROUND((CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS IndexSize_MB,
    CAST(ROUND((CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSize_MB,
    --'| |' Separator_MB_GB,
    CAST(ROUND(((a1.reserved + ISNULL(a4.reserved,0)) * 8) / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS ReservedSize_GB,
    CAST(ROUND(a1.data * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS DataSize_GB,
    CAST(ROUND((CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS IndexSize_GB,
    CAST(ROUND((CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 / 1024.00 / 1024.00, 2) AS NUMERIC(36, 2)) AS UnusedSize_GB
FROM
    (SELECT 
        ps.object_id,
        SUM (CASE WHEN (ps.index_id < 2) THEN row_count ELSE 0 END) AS [rows],
        SUM (ps.reserved_page_count) AS reserved,
        SUM (CASE
                WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END
            ) AS data,
        SUM (ps.used_page_count) AS used
    FROM sys.dm_db_partition_stats ps
        --===Remove the following comment for SQL Server 2014+
        --WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized = 1)
    GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN 
    (SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS reserved,
        SUM(ps.used_page_count) AS used
     FROM sys.dm_db_partition_stats ps
     INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
     WHERE it.internal_type IN (202,204)
     GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id ) 
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
--AND a2.name = 'MyTable'       --Filter for specific table
--ORDER BY a3.name, a2.name
ORDER BY ReservedSize_MB DESC

ayrıca daha iyi sıralama düzeni.
Pxtl

Bu en iyi cevap olmalı.
Baodad

14

Azure için bunu kullandım:

SSMS v17.x'e sahip olmalısınız

Kullandım;

resim açıklamasını buraya girin

Bununla, Kullanıcı Serçe'nin de belirttiği gibi :

Databases> Öğenizi açın ve Tablolar'ı seçin , ardından F7
tuşuna basın Aşağıdakirow count
gibi görmelisiniz : resim açıklamasını buraya girin

Buradaki SSMS , Azure veritabanlarına bağlı


3
F7 çok az kullanılıyor.
cskwg

1
Bunun var olduğu hakkında hiçbir fikrim yoktu, kendimden biraz utanıyorum: p Teşekkürler!
lollancf37

Bellek optimize tablolar ile ilgili bir sorun var, (ben sadece bu yazı gördükten sonra test :)
Amirreza

11

Tablo bölümleme kullanıyoruz ve yinelenen kayıtlar nedeniyle yukarıda verilen sorgularda bazı sorunlar yaşadık.

Buna ihtiyaç duyanlar için, "Tabloya göre disk kullanımı" raporunu oluştururken SQL Server 2014 tarafından çalıştırılan sorgunun altında bulabilirsiniz. SQL Server'ın önceki sürümleriyle de çalıştığını varsayıyorum.

Mucizevi şekilde çalışır.

SELECT
    a2.name AS [tablename],
    a1.rows as row_count,
    (a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved, 
    a1.data * 8 AS data,
    (CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
    (CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused
FROM
    (SELECT 
        ps.object_id,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN row_count
                ELSE 0
            END
            ) AS [rows],
        SUM (ps.reserved_page_count) AS reserved,
        SUM (
            CASE
                WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count)
            END
            ) AS data,
        SUM (ps.used_page_count) AS used
    FROM sys.dm_db_partition_stats ps
        WHERE ps.object_id NOT IN (SELECT object_id FROM sys.tables WHERE is_memory_optimized = 1)
    GROUP BY ps.object_id) AS a1
LEFT OUTER JOIN 
    (SELECT 
        it.parent_id,
        SUM(ps.reserved_page_count) AS reserved,
        SUM(ps.used_page_count) AS used
     FROM sys.dm_db_partition_stats ps
     INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
     WHERE it.internal_type IN (202,204)
     GROUP BY it.parent_id) AS a4 ON (a4.parent_id = a1.object_id)
INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id ) 
INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)
WHERE a2.type <> N'S' and a2.type <> N'IT'
ORDER BY a3.name, a2.name

SSMS'nin yaptığıyla eşleşen ve bölümleri düzgün işleyen bir komut dosyası için teşekkürler.
Mike

8
-- Show the size of all the tables in a database sort by data size descending
SET NOCOUNT ON
DECLARE @TableInfo TABLE (tablename varchar(255), rowcounts int, reserved varchar(255), DATA varchar(255), index_size varchar(255), unused varchar(255))
DECLARE @cmd1 varchar(500)
SET @cmd1 = 'exec sp_spaceused ''?'''

INSERT INTO @TableInfo (tablename,rowcounts,reserved,DATA,index_size,unused)
EXEC sp_msforeachtable @command1=@cmd1

SELECT * FROM @TableInfo ORDER BY Convert(int,Replace(DATA,' KB','')) DESC

8

Mar_c'nin cevabında küçük bir değişiklik , çünkü bu sayfaya sık sık geri dönüyorum, çoğu satırın ilk tarafından sipariş edildi:

SELECT
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB,
    SUM(a.used_pages) * 8 AS UsedSpaceKB,
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM
    sys.tables t
INNER JOIN
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN
    sys.schemas s ON t.schema_id = s.schema_id
WHERE
    t.NAME NOT LIKE 'dt%'
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255
GROUP BY
    t.Name, s.Name, p.Rows
ORDER BY
    --p.rows DESC --Uncomment to order by amount rows instead of size in KB.
    SUM(a.total_pages) DESC 

5

Bu size her tablo için boyutlar ve kayıt sayıları verecektir.

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
-- Get a list of tables and their sizes on disk
ALTER PROCEDURE [dbo].[sp_Table_Sizes]
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
DECLARE @table_name VARCHAR(500)  
DECLARE @schema_name VARCHAR(500)  
DECLARE @tab1 TABLE( 
        tablename VARCHAR (500) collate database_default 
       ,schemaname VARCHAR(500) collate database_default 
) 

CREATE TABLE #temp_Table ( 
        tablename sysname 
       ,row_count INT 
       ,reserved VARCHAR(50) collate database_default 
       ,data VARCHAR(50) collate database_default 
       ,index_size VARCHAR(50) collate database_default 
       ,unused VARCHAR(50) collate database_default  
) 

INSERT INTO @tab1  
SELECT Table_Name, Table_Schema  
FROM information_schema.tables  
WHERE TABLE_TYPE = 'BASE TABLE' 

DECLARE c1 CURSOR FOR 
SELECT Table_Schema + '.' + Table_Name   
FROM information_schema.tables t1  
WHERE TABLE_TYPE = 'BASE TABLE' 

OPEN c1 
FETCH NEXT FROM c1 INTO @table_name 
WHILE @@FETCH_STATUS = 0  
BEGIN   
        SET @table_name = REPLACE(@table_name, '[','');  
        SET @table_name = REPLACE(@table_name, ']','');  

        -- make sure the object exists before calling sp_spacedused 
        IF EXISTS(SELECT id FROM sysobjects WHERE id = OBJECT_ID(@table_name)) 
        BEGIN 
               INSERT INTO #temp_Table EXEC sp_spaceused @table_name, false; 
        END 

        FETCH NEXT FROM c1 INTO @table_name 
END 
CLOSE c1 
DEALLOCATE c1 

SELECT  t1.* 
       ,t2.schemaname  
FROM #temp_Table t1  
INNER JOIN @tab1 t2 ON (t1.tablename = t2.tablename ) 
ORDER BY schemaname,t1.tablename; 

DROP TABLE #temp_Table
END

2
Kod, XML veya veri örnekleri gönderiyorsanız, LÜTFEN metin düzenleyicisinde bu satırları vurgulayın ve { }güzel biçimlendirmek ve sözdizimi vurgulamak için düzenleyici araç çubuğundaki "kod örnekleri" düğmesini ( ) tıklayın !
marc_s

4

Bir veritabanındaki tüm tablo boyutlarını almak için bu sorguyu kullanabilirsiniz:

Exec sys.sp_MSforeachtable ' sp_spaceused "?" '

Ve tüm sonucu geçici tabloya eklemek ve bundan sonra geçici tablodan seçim yapmak için değiştirebilirsiniz.

Insert into #TempTable Exec sys.sp_MSforeachtable ' sp_spaceused "?" ' 
Select * from #TempTable

3

OSQL kullanan bir komut isteminden :

OSQL -E -d <*databasename*> -Q "exec sp_msforeachtable 'sp_spaceused [?]'" > result.txt

3

Aşağıdaki adımlarla tüm tabloların boyutlarını hızlı bir şekilde almanın bir yolu:

  1. Tüm veritabanı tablolarını listelemek için verilen T-SQL komutlarını yazın:

    select 'exec sp_spaceused ' + TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_TYPE = 'BASE TABLE'
  2. Şimdi veritabanı tablolarının listesini kopyalayın ve yeni bir sorgu analizörü penceresine kopyalayın

    exec sp_spaceused table1
    exec sp_spaceused table2
    exec sp_spaceused table3
    exec sp_spaceused table4
    exec sp_spaceused table5
  3. SQL sorgu çözümleyicisinde , Dosyaya ( Ctrl+ Shift+ F) ilişkin sonuçlar üst araç çubuğu seçeneğini belirleyin .

  4. Son olarak, yukarıdaki araç çubuğundan işaretlenmiş olan Execute düğmesine kırmızı basın .

  5. Tüm tabloların Veritabanı boyutu artık bilgisayarınızdaki bir dosyada depolanmaktadır.

    Resim açıklamasını buraya girin


2

Marc_s cevabının üstüne birkaç sütun daha ekledim:

with fs
as
(
select i.object_id,
        p.rows AS RowCounts,
        SUM(a.total_pages) * 8 AS TotalSpaceKb
from     sys.indexes i INNER JOIN 
        sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id INNER JOIN 
         sys.allocation_units a ON p.partition_id = a.container_id
WHERE 
    i.OBJECT_ID > 255 
GROUP BY 
    i.object_id,
    p.rows
)

SELECT 
    t.NAME AS TableName,
    fs.RowCounts,
    fs.TotalSpaceKb,
    t.create_date,
    t.modify_date,
    ( select COUNT(1)
        from sys.columns c 
        where c.object_id = t.object_id ) TotalColumns    
FROM 
    sys.tables t INNER JOIN      
    fs  ON t.OBJECT_ID = fs.object_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
ORDER BY 
    t.Name

1

Yayımım yalnızca SQL Server 2000 ile ilgilidir ve ortamımda çalıştığı test edilmiştir.

Bu kod , yalnızca tek bir veritabanına değil, tek bir örneğin tüm olası veritabanlarına erişir .

Uygun verileri toplamak ve daha sonra sonuçları bir 'Canlı' tabloya dökmek için iki geçici tablo kullanıyorum.

Döndürülen veriler: DatabaseName, DatabaseTableName, Satırlar (Tabloda), veri (KB'deki tablonun boyutu göründüğü gibi), giriş verileri (Bu komut dosyasını en son ne zaman çalıştırdığımı bilmek için yararlı buluyorum).

Bu koda düşen dezavantajı 'data' alanı int olarak saklanmamıştır ('KB' karakterleri bu alanda tutulur) ve bu sıralama için yararlı olacaktır (ancak tamamen gerekli değildir).

Umarım bu kod orada birine yardımcı olur ve biraz zaman kazandırır!

CREATE PROCEDURE [dbo].[usp_getAllDBTableSizes]

AS
BEGIN
   SET NOCOUNT OFF

   CREATE TABLE #DatabaseTables([dbname] sysname,TableName sysname)
   CREATE TABLE #AllDatabaseTableSizes(Name sysname,[rows] VARCHAR(18), reserved VARCHAR(18), data VARCHAR(18), index_size VARCHAR(18), unused VARCHAR(18))

   DECLARE @SQL nvarchar(4000)
   SET @SQL='select ''?'' AS [Database], Table_Name from [?].information_schema.tables WHERE TABLE_TYPE = ''BASE TABLE'' '

   INSERT INTO #DatabaseTables(DbName, TableName)
      EXECUTE sp_msforeachdb @Command1=@SQL

   DECLARE AllDatabaseTables CURSOR LOCAL READ_ONLY FOR   
   SELECT TableName FROM #DatabaseTables

   DECLARE AllDatabaseNames CURSOR LOCAL READ_ONLY FOR   
   SELECT DBName FROM #DatabaseTables

   DECLARE @DBName sysname  
   OPEN AllDatabaseNames  

   DECLARE @TName sysname
   OPEN AllDatabaseTables  

   WHILE 1=1 BEGIN 
      FETCH NEXT FROM AllDatabaseNames INTO @DBName  
      FETCH NEXT FROM AllDatabaseTables INTO @TName 
      IF @@FETCH_STATUS<>0 BREAK  
      INSERT INTO #AllDatabaseTableSizes
         EXEC ( 'EXEC ' + @DBName + '.dbo.sp_spaceused ' + @TName) 

   END 

   --http://msdn.microsoft.com/en-us/library/aa175920(v=sql.80).aspx
   INSERT INTO rsp_DatabaseTableSizes (DatabaseName, name, [rows], data)
      SELECT   [dbname], name, [rows],  data FROM #DatabaseTables
      INNER JOIN #AllDatabaseTableSizes
      ON #DatabaseTables.TableName = #AllDatabaseTableSizes.Name
      GROUP BY [dbname] , name, [rows],  data
      ORDER BY [dbname]
   --To be honest, I have no idea what exact duplicates we are dropping
    -- but in my case a near enough approach has been good enough.
   DELETE FROM [rsp_DatabaseTableSizes]
   WHERE name IN 
      ( 
      SELECT name 
      FROM [rsp_DatabaseTableSizes]
      GROUP BY name
      HAVING COUNT(*) > 1
      )

   DROP TABLE #DatabaseTables
   DROP TABLE #AllDatabaseTableSizes

   CLOSE AllDatabaseTables  
   DEALLOCATE AllDatabaseTables  

   CLOSE AllDatabaseNames  
   DEALLOCATE AllDatabaseNames      
END

--EXEC [dbo].[usp_getAllDBTableSizes] 

Bilmeniz gerekirse , rsp_DatabaseTableSizes tablosu şu yollarla oluşturuldu:

CREATE TABLE [dbo].[rsp_DatabaseSizes](
    [DatabaseName] [varchar](1000) NULL,
    [dbSize] [decimal](15, 2) NULL,
    [DateUpdated] [smalldatetime] NULL
) ON [PRIMARY]

GO

1

Marc_s'in cevabına (kabul edilen cevap) basit bir uzantı olarak, bu sütun sayısını döndürmek ve filtrelemeye izin vermek için ayarlanır:

SELECT *
FROM
(

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    COUNT(DISTINCT c.COLUMN_NAME) as ColumnCount,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    (SUM(a.used_pages) * 8) AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
INNER JOIN
    INFORMATION_SCHEMA.COLUMNS c ON t.NAME = c.TABLE_NAME
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME NOT LIKE 'dt%' 
    AND t.is_ms_shipped = 0
    AND i.OBJECT_ID > 255
GROUP BY 
    t.Name, s.Name, p.Rows
) AS Result

WHERE
    RowCounts > 1000
    AND ColumnCount > 10
ORDER BY 
    UsedSpaceKB DESC

Sütunlar tablosuna katıldıktan sonra, artık doğru tablo alanınız yok. Dış uygulama düzeltme olacaktır.
dreamca4er

0

Yukarıdaki @Mark cevabına dayanarak, en son boyut istatistiklerini zorlamak için @ updateusage = 'true' eklendi ( https://msdn.microsoft.com/en-us/library/ms188776.aspx ):

        SET NOCOUNT ON
        DECLARE @TableInfo TABLE (tablename varchar(255), rowcounts int, reserved varchar(255), DATA varchar(255), index_size varchar(255), unused varchar(255))
        DECLARE @cmd1 varchar(500)
        SET @cmd1 = 'exec sp_spaceused @objname =''?'', @updateusage =''true'' '

        INSERT INTO @TableInfo (tablename,rowcounts,reserved,DATA,index_size,unused)
        EXEC sp_msforeachtable @command1=@cmd1 
SELECT * FROM @TableInfo ORDER BY Convert(int,Replace(DATA,' KB','')) DESC

0

Aşağıda, boyutuna göre azalan şekilde 1 GB'den büyük tablolar almak için örnek bir sorgu verilmiştir.

USE YourDB
GO

DECLARE @Mult float = 8
SET @Mult = @Mult / POWER(2, 20) -- Use POWER(2, 10) for MBs

; WITH CTE AS
(
SELECT
    i.object_id,
    Rows = MAX(p.rows),
    TotalSpaceGB = ROUND(SUM(a.total_pages) * @Mult, 0),
    UsedSpaceGB = ROUND(SUM(a.used_pages) * @Mult, 0)
FROM 
    sys.indexes i
JOIN
    sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
JOIN
    sys.allocation_units a ON p.partition_id = a.container_id
WHERE
    i.object_id > 255
GROUP BY
    i.object_id
HAVING
    SUM(a.total_pages) * @Mult > 1
)
SELECT 
    SchemaName = s.name,
    TableName = t.name,
    c.TotalSpaceGB,
    c.UsedSpaceGB,
    UnusedSpaceGB = c.TotalSpaceGB - c.UsedSpaceGB,
    [RowCount] = c.Rows
FROM 
    CTE c
JOIN    
    sys.tables t ON t.object_id = c.object_id
JOIN
    sys.schemas s ON t.schema_id = s.schema_id
ORDER BY
    c.TotalSpaceGB DESC
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.