2008-11-25 36 views
70

Chúng ta có thể có truy vấn SQL về cơ bản sẽ giúp xem kích thước bảng và chỉ mục trong Máy chủ SQl.Kích thước bảng và chỉ mục trong SQL Server

Cách máy chủ SQL duy trì mức sử dụng bộ nhớ cho bảng/chỉ mục?

+0

Đã có câu trả lời cho điều này, nhưng cá nhân tôi sử dụng truy vấn trong liên kết này: http: // qualityofdata. com/2011/02/02/analise-table-space-usage-in-sql-server/ – naiem

+0

Bạn cũng có thể tìm thấy thủ tục được lưu trữ 'sp_helpdb' hữu ích –

Trả lời

65

exec sp_spaceused không có tham số hiển thị tóm tắt cho toàn bộ cơ sở dữ liệu. Giải pháp cho phép có thể tạo ra một tập hợp kết quả cho mỗi bảng - mà SSMS có thể không xử lý được nếu bạn có quá nhiều bảng.

Tôi đã tạo một script để thu thập các bảng thông tin qua sp_spaceused và hiển thị bản tóm tắt trong một bộ bản ghi duy nhất, được sắp xếp theo kích thước.

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

Tập lệnh của bạn chỉ xử lý các bảng trong lược đồ 'dbo'. Nếu tôi có một bảng trong cơ sở dữ liệu của tôi với một lược đồ 'Kiểm toán', sp_spaceused cần phải được gọi như thế này: exec sp_spaceused 'Audit.Data'.Vì vậy, kịch bản cần phải được sửa đổi để cung cấp cho nó tên bảng được đặt trước bằng tên lược đồ (được phân tách bằng dấu chấm) để nó trả về dữ liệu về các bảng từ các lược đồ khác. – Baodad

+1

Điểm tốt @Boadad ... đó phải là một sửa chữa siêu dễ dàng. Thay thế "chọn tên từ sysobjects trong đó xtype = 'U'" bằng cách này, hãy làm như sau: "select '[' + sc.name + ']. [' + S.name + ']' TỪ sysobjects s ​​ INNER THAM GIA sys.schemas sc ON s.uid = sc.schema_id trong đó s.xtype = 'U' " Kịch bản tuyệt vời, cảm ơn! – DCaugs

+0

thay vì sử dụng bảng tạm thời, chúng tôi có thể chèn dữ liệu vào bảng khác không phải là tạm thời không? – ldevp

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

Nếu bạn đăng mã, XML hoặc mẫu dữ liệu, ** XIN ** làm nổi bật những dòng đó trong trình soạn thảo văn bản và nhấp vào nút "mẫu mã" ('{}') trên thanh công cụ của trình soạn thảo để định dạng và cú pháp độc đáo làm nổi bật nó! –

0

Có thủ tục được lưu trữ mở rộng sp_spaceused để nhận thông tin này. Nó khá phức tạp để làm điều đó từ các dữ liệu từ điển, nhưng This link người hâm mộ ra một kịch bản mà nó. This stackoverflow question có một số thông tin về các cấu trúc dữ liệu cơ bản mà bạn có thể sử dụng để xây dựng các ước tính về kích thước bảng và chỉ mục cho lập kế hoạch capcity.

107

sp_spaceused cung cấp cho bạn kích thước của tất cả các chỉ mục được kết hợp.

Nếu bạn muốn kích thước của mỗi chỉ số cho một bảng, sử dụng một trong hai truy vấn sau đây:

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 

Các kết quả thường hơi khác nhau nhưng không quá 1%.

+0

Truy vấn đầu tiên bao gồm các khóa chính, điều này hơi khó hiểu vì một vài lý do. – quillbreaker

+0

Truy vấn thứ hai ném 'Msg 102, Cấp 15, Tiểu bang 1, Dòng 5 - Cú pháp không chính xác gần '(' .' vào tôi, nhưng tôi không thể thấy bất kỳ vấn đề nào với cú pháp. Ý tưởng nào? – Oliver

+0

Oliver, phiên bản nào là bạn hoạt động như thế nào cho tôi trong năm 2008R2 và 2012. –

15

Mở SQL 2012 bị thông tin này về mặt kĩ bảng đã trở thành ngon đơn giản:

SQL Management Studio -> Nhấp chuột phải vào Db -> Báo cáo -> Báo cáo Tiêu chuẩn -> Sử dụng đĩa bằng bảng!

Thưởng thức

3

Đây là nhỏ gọn hơn phiên bản của câu trả lời thành công nhất:

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 
3

nó là một thời gian dài kể từ khi thành lập cho bài này nhưng tôi muốn chia sẻ kịch bản của tôi:

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 

hoạt động cho:

  • SQL Server (bắt đầu với năm 2008)
  • Bao gồm thông tin cho tất cả các bảng mỗi cơ sở dữ liệu hiện tại
2
--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; 
Các vấn đề liên quan