Chúng ta có thể có một truy vấn SQL về cơ bản sẽ giúp xem kích thước bảng và chỉ mục trong SQl Server không.
Làm cách nào máy chủ SQL duy trì việc sử dụng bộ nhớ cho các bảng / chỉ mục?
Chúng ta có thể có một truy vấn SQL về cơ bản sẽ giúp xem kích thước bảng và chỉ mục trong SQl Server không.
Làm cách nào máy chủ SQL duy trì việc sử dụng bộ nhớ cho các bảng / chỉ mục?
Câu trả lời:
Các exec sp_spaceused
không tham số hiển thị tóm tắt cho toàn bộ cơ sở dữ liệu. Giải pháp foreachtable tạo một tập hợp kết quả cho mỗi bảng - SSMS có thể không xử lý được nếu bạn có quá nhiều bảng.
Tôi đã tạo một tập lệnh thu thập thông tin bảng thông qua sp_spaceused
và hiển thị một bản tóm tắt trong một tập hợp 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
#
.
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ỉ mục cho một bảng, hãy sử dụng một trong hai truy vấn sau:
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
Kết quả thường hơi khác một chút nhưng trong vòng 1%.
Msg 102, Level 15, State 1, Line 5 - Incorrect syntax near '('.
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. Bất kỳ ý tưởng?
Trên SQL 2012, việc lấy thông tin này ở cấp bảng đã trở nên rất đơn giản:
SQL Management Studio -> Nhấp chuột phải vào Db -> Báo cáo -> Báo cáo Chuẩn -> Sử dụng đĩa theo bảng!
Thưởng thức
--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;
Đây là phiên bản nhỏ gọn hơ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
Đã lâu kể từ khi tạo bài đăng này nhưng tôi muốn chia sẻ kịch bản của mình:
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
nó hoạt động cho:
Có một thủ tục được lưu trữ mở rộng sp_spaceused
để đưa thông tin này ra ngoài. Nó khá phức tạp để làm điều đó từ từ điển dữ liệu, nhưng Điều này liên kết người hâm mộ với một tập lệnh thực hiện điều đó. Câu hỏi stackoverflow này có một số thông tin về cấu trúc dữ liệu cơ bản mà bạn có thể sử dụng để xây dựng ước tính về kích thước bảng và chỉ mục cho việc lập kế hoạch thành công.
Truy vấn này đến từ hai câu trả lời khác:
Nhận kích thước của tất cả các bảng trong cơ sở dữ liệu
Làm cách nào để tìm các đối tượng lớn nhất trong cơ sở dữ liệu SQL Server?
, nhưng tôi đã nâng cao điều này để trở nên phổ biến. Nó sử dụng sys.objects
từ điển:
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
;
sp_helpdb
hữu ích