SQL Server'da Tablo ve Dizin boyutu


91

Temelde SQl Server'da tablo ve dizin boyutlarını görüntülemeye yardımcı olacak bir SQL sorgusu alabilir miyiz?

SQL sunucusu tablolar / dizinler için bellek kullanımını nasıl sağlar?


1
Ayrıca saklı yordamı sp_helpdbyararlı bulabilirsiniz
Zack Burt

1
Buna zaten cevaplar var, ancak ben şahsen bu bağlantıdaki sorguyu kullanıyorum: qualityofdata.com/2011/02/02/…
naiem

Yanıtlar:


74

exec sp_spaceusedParametresi olmadan tüm veritabanı için özetini gösterir. Öngörülebilir çözüm, tablo başına bir sonuç kümesi oluşturur - çok fazla tablonuz varsa SSMS bunu işleyemeyebilir.

Tablo bilgilerini toplayan ve tek bir kayıt kümesinde boyuta göre sıralanmış bir özet görüntüleyen bir betik oluşturdum sp_spaceused.

create table #t
(
  name nvarchar(128),
  rows varchar(50),
  reserved varchar(50),
  data varchar(50),
  index_size varchar(50),
  unused varchar(50)
)

declare @id nvarchar(128)
declare c cursor for
select '[' + sc.name + '].[' + s.name + ']' FROM sysobjects s INNER JOIN sys.schemas sc ON s.uid = sc.schema_id where s.xtype='U'

open c
fetch c into @id

while @@fetch_status = 0 begin

  insert into #t
  exec sp_spaceused @id

  fetch c into @id
end

close c
deallocate c

select * from #t
order by convert(int, substring(data, 1, len(data)-3)) desc

drop table #t

4
Komut dosyanız yalnızca 'dbo' şemasındaki tabloları işler. Veritabanımda 'Audit' şemasına sahip bir tablom varsa, sp_spaceused şu şekilde çağrılmalıdır: exec sp_spaceused 'Audit.Data'. Bu nedenle, komut dosyasının, diğer şemalardan tablolar hakkında veri döndürmesi için, önünde şema adı (nokta ile ayrılmış) bulunan tablo adını besleyecek şekilde değiştirilmesi gerekir.
Baodad

1
İyi nokta @Boadad ... bu süper kolay bir düzeltme olmalı. "Xtype = 'U' olduğu sistem nesnelerinden isim seç" i bununla değiştirmek hile yapmalıdır: "'[' + sc.name + '] seçin. [' + S.name + ']' sysobjects s ​​INNER JOIN sys .schemas sc AÇIK s.uid = sc.schema_id, burada s.xtype = 'U' "Harika komut dosyası, teşekkürler!
DCaugs

geçici tablo kullanmak yerine başka bir tabloya geçici olmayan veri ekleyebilir miyiz?
prab2112

@PrabhakarPandey Elbette sadece #.
Racer SQL

120

sp_spaceused size birleştirilmiş tüm dizinlerin boyutunu verir.

Bir tablo için her dizinin boyutunu istiyorsanız, şu iki sorudan birini kullanın:

SELECT
    i.name                  AS IndexName,
    SUM(s.used_page_count) * 8   AS IndexSizeKB
FROM sys.dm_db_partition_stats  AS s 
JOIN sys.indexes                AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
WHERE s.[object_id] = object_id('dbo.TableName')
GROUP BY i.name
ORDER BY i.name

SELECT
    i.name              AS IndexName,
    SUM(page_count * 8) AS IndexSizeKB
FROM sys.dm_db_index_physical_stats(
    db_id(), object_id('dbo.TableName'), NULL, NULL, 'DETAILED') AS s
JOIN sys.indexes AS i
ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id
GROUP BY i.name
ORDER BY i.name

Sonuçlar genellikle biraz farklıdır ancak% 1 içindedir.


İlk sorgu, birkaç nedenden dolayı biraz kafa karıştırıcı olan birincil anahtarları içerir.
quillbreaker

İkinci sorgu Msg 102, Level 15, State 1, Line 5 - Incorrect syntax near '('.bana fırlıyor , ancak sözdizimiyle ilgili herhangi bir sorun göremiyorum. Herhangi bir fikir?
Oliver

Oliver, hangi versiyonu kullanıyorsun? Benim için 2008R2 ve 2012'de olduğu gibi çalışıyor.
Rob Garrison

24

SQL 2012'de bu bilgileri tablo düzeyinde almak oldukça basit hale geldi:

SQL Management Studio -> Db'ye sağ tıklayın -> Raporlar -> Standart Raporlar -> Tabloya göre disk kullanımı!

Zevk almak


13
EXEC sp_MSforeachtable @command1="EXEC sp_spaceused '?'"

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

4

İşte en başarılı cevabın daha kompakt versiyonu:

create table #tbl(
  name nvarchar(128),
  rows varchar(50),
  reserved varchar(50),
  data varchar(50),
  index_size varchar(50),
  unused varchar(50)
)

exec sp_msforeachtable 'insert into #tbl exec sp_spaceused [?]'

select * from #tbl
    order by convert(int, substring(data, 1, len(data)-3)) desc

drop table #tbl

4
--Gets the size of each index for the specified table
DECLARE @TableName sysname = N'SomeTable';

SELECT i.name AS IndexName
      ,8 * SUM(s.used_page_count) AS IndexSizeKB
FROM sys.indexes AS i
    INNER JOIN sys.dm_db_partition_stats AS s 
        ON i.[object_id] = s.[object_id] AND i.index_id = s.index_id
WHERE s.[object_id] = OBJECT_ID(@TableName, N'U')
GROUP BY i.name
ORDER BY i.name;

SELECT i.name AS IndexName
      ,8 * SUM(a.used_pages) AS IndexSizeKB
FROM sys.indexes AS i
    INNER JOIN sys.partitions AS p 
        ON i.[object_id]  = p.[object_id] AND i.index_id = p.index_id
    INNER JOIN sys.allocation_units AS a 
        ON p.partition_id = a.container_id
WHERE i.[object_id] = OBJECT_ID(@TableName, N'U')
GROUP BY i.name
ORDER BY i.name;

3

Bu yazının oluşturulmasının üzerinden uzun zaman geçti, ancak senaryomu paylaşmak istedim:

WITH CteIndex
AS
(
SELECT 
     reservedpages = (reserved_page_count)
     ,usedpages = (used_page_count)
     ,pages = (
            CASE
                WHEN (s.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
            )    
     ,s.object_id   
     ,i.index_id        
     ,i.type_desc AS IndexType
     ,i.name AS indexname
    FROM sys.dm_db_partition_stats s
    INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id] AND s.index_id = i.index_id   
)
SELECT DISTINCT
DB_NAME(DB_ID()) AS DatabaseName
,o.name AS TableName
,o.object_id
,ct.indexname
,ct.IndexType
,ct.index_id
, IndexSpace = LTRIM (STR ((CASE WHEN usedpages > pages THEN CASE WHEN ct.index_id < 2 THEN  pages ELSE (usedpages - pages) END ELSE 0 END) * 8, 15, 0) + ' KB')
FROM CteIndex ct
INNER JOIN sys.objects o ON o.object_id = ct.object_id
INNER JOIN sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL , NULL) ps ON ps.object_id = o.object_id
AND ps.index_id = ct.index_id
ORDER BY name ASC

Bu şunun için çalışır:

  • SQL Server (2008'den itibaren)
  • Geçerli veritabanı başına tüm tablolar için bilgi içerir

0

sp_spaceusedBu bilgileri alan genişletilmiş bir saklı yordam vardır. Bunu veri sözlüğünden yapmak oldukça karmaşık, ancak Bu bağlantı , bunu yapan bir komut dosyasına yayılıyor. Bu yığın aşımı sorusu , kapasite planlaması için tablo ve dizin boyutlarının tahminlerini oluşturmak için kullanabileceğiniz temel veri yapıları hakkında bilgi için bir miktar yelpazeye sahiptir.


0

Bu sorgu iki başka cevaptan geliyor:

Veritabanındaki tüm tabloların boyutunu alın

Bir SQL Server veritabanındaki en büyük nesneler nasıl bulunur?

ama bunu evrensel olacak şekilde geliştirdim. sys.objectsSözlüğü kullanır :

SELECT 
    s.NAME as SCHEMA_NAME,
    t.NAME AS OBJ_NAME,
    t.type_desc as OBJ_TYPE,
    i.name as indexName,
    sum(p.rows) as RowCounts,
    sum(a.total_pages) as TotalPages, 
    sum(a.used_pages) as UsedPages, 
    sum(a.data_pages) as DataPages,
    (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, 
    (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, 
    (sum(a.data_pages) * 8) / 1024 as DataSpaceMB
FROM 
    sys.objects t
INNER JOIN
    sys.schemas s ON t.SCHEMA_ID = s.SCHEMA_ID 
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
WHERE 
    t.NAME NOT LIKE 'dt%' AND
    i.OBJECT_ID > 255 AND   
    i.index_id <= 1
GROUP BY 
    s.NAME, t.NAME, t.type_desc, i.object_id, i.index_id, i.name 
ORDER BY
    sum(a.total_pages) DESC
;

0

Tek bir tablonun (ve dizinlerinin) depolama verilerini görmek için:

exec sp_spaceused MyTable
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.