Tabel dan ukuran Indeks di SQL Server

90

Bisakah kita memiliki kueri SQL yang pada dasarnya akan membantu dalam melihat tabel dan ukuran indeks di SQl Server.

Bagaimana SQL server mempertahankan penggunaan memori untuk tabel / indeks?

Kamal Joshi
sumber
1
Anda juga dapat menemukan prosedur tersimpan sp_helpdbberguna
Zack Burt
1
Sudah ada jawaban untuk ini, tapi saya pribadi menggunakan kueri di tautan ini: qualityofdata.com/2011/02/02/…
naiem

Jawaban:

73

The exec sp_spaceusedtanpa parameter menunjukkan ringkasan untuk seluruh database. Solusi yang dapat diperkirakan menghasilkan satu kumpulan hasil per tabel - yang mungkin tidak dapat ditangani oleh SSMS jika Anda memiliki terlalu banyak tabel.

Saya membuat skrip yang mengumpulkan info tabel melalui sp_spaceuseddan menampilkan ringkasan dalam satu kumpulan catatan, diurutkan berdasarkan ukuran.

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
devio
sumber
4
Skrip Anda hanya menangani tabel dalam skema 'dbo'. Jika saya memiliki tabel di database saya dengan skema 'Audit', sp_spaceused perlu dipanggil seperti ini: exec sp_spaceused 'Audit.Data'. Jadi skrip perlu dimodifikasi untuk memberinya nama tabel yang diawali dengan nama skema (dipisahkan oleh titik) untuk mengembalikan data tentang tabel dari skema lain.
Baodad
1
Poin bagus @Boadad ... itu seharusnya perbaikan yang sangat mudah. Mengganti "pilih nama dari sysobjects where xtype = 'U'" dengan ini seharusnya melakukan trik: "pilih '[' + sc.name + ']. [' + S.name + ']' FROM sysobjects s ​​INNER JOIN sys .schemas sc ON s.uid = sc.schema_id where s.xtype = 'U' "Skrip yang bagus, terima kasih!
DCaugs
Daripada menggunakan tabel sementara, bisakah kita memasukkan data ke tabel lain yang tidak bersifat sementara?
ID
@PrabhakarPandey Tentu saja hapus #.
Pembalap SQL
120

sp_spaceused memberi Anda ukuran dari semua indeks yang digabungkan.

Jika Anda menginginkan ukuran setiap indeks untuk tabel, gunakan salah satu dari dua kueri berikut:

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

Hasilnya biasanya sedikit berbeda tetapi dalam 1%.

Rob Garrison
sumber
Kueri pertama menyertakan kunci utama, yang agak membingungkan karena beberapa alasan.
quillbreaker
Kueri kedua melontarkan Msg 102, Level 15, State 1, Line 5 - Incorrect syntax near '('.saya, tetapi saya tidak dapat melihat masalah apa pun dengan sintaksnya. Ada ide?
Oliver
Oliver, versi apa yang Anda jalankan? Ini berfungsi apa adanya untuk saya di 2008R2 dan 2012.
Rob Garrison
24

Di SQL 2012, mendapatkan informasi ini di tingkat tabel menjadi sangat sederhana:

SQL Management Studio -> Klik kanan pada Db -> Laporan -> Laporan Standar -> Penggunaan disk berdasarkan tabel!

Nikmati

penduduk bumi42
sumber
13
EXEC sp_MSforeachtable @command1="EXEC sp_spaceused '?'"
Ben R
sumber
3
Jika Anda memposting kode, XML, atau sampel data, TOLONG sorot baris tersebut di editor teks dan klik tombol "sampel kode" ( { }) pada bilah alat editor untuk memformat dan menyorotnya dengan sintaks!
marc_s
4

Berikut adalah versi yang lebih ringkas dari jawaban paling sukses:

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
alpav
sumber
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;
Alex
sumber
3

sudah lama sejak pembuatan posting ini tetapi saya ingin membagikan skrip saya:

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

itu bekerja untuk:

  • SQL Server (dimulai dengan 2008)
  • Termasuk info untuk semua tabel per database saat ini
jthalliens.dll
sumber
0

Ada prosedur tersimpan yang diperpanjang sp_spaceusedyang mengeluarkan informasi ini. Cukup berbelit-belit untuk melakukannya dari kamus data, tetapi Tautan ini mengarah ke skrip yang melakukannya. Pertanyaan stackoverflow ini memiliki beberapa informasi tentang struktur data yang mendasari yang dapat Anda gunakan untuk membuat perkiraan ukuran tabel dan indeks untuk perencanaan kapasitas.

ConcernedOfTunbridgeWells
sumber
0

Kueri ini berasal dari dua jawaban lain:

Dapatkan ukuran semua tabel dalam database

Bagaimana cara menemukan objek terbesar dalam database SQL Server?

, tapi saya meningkatkan ini menjadi universal. Ini menggunakan sys.objectskamus:

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
;
Jakub P.
sumber