【发布时间】:2011-01-06 20:33:51
【问题描述】:
如何在 SQL Server 数据库中查找最大的对象?首先,通过确定哪些表(和相关索引)最大,然后确定特定表中的哪些行最大(我们将二进制数据存储在 BLOB 中)?
是否有任何工具可以帮助进行这种数据库分析?或者我可以对系统表运行一些简单的查询吗?
【问题讨论】:
标签: sql-server database
如何在 SQL Server 数据库中查找最大的对象?首先,通过确定哪些表(和相关索引)最大,然后确定特定表中的哪些行最大(我们将二进制数据存储在 BLOB 中)?
是否有任何工具可以帮助进行这种数据库分析?或者我可以对系统表运行一些简单的查询吗?
【问题讨论】:
标签: sql-server database
多年来,我一直在使用这个 SQL 脚本(我从某个地方的某个人那里得到的 - 无法重建它来自谁),它帮助我理解并确定了索引和表的大小:
SELECT
t.name AS TableName,
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.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
WHERE
t.name NOT LIKE 'dt%' AND
i.object_id > 255 AND
i.index_id <= 1
GROUP BY
t.name, i.object_id, i.index_id, i.name
ORDER BY
object_name(i.object_id)
当然,您可以使用其他排序条件,例如
ORDER BY SUM(p.rows) DESC
获取行数最多的表,或
ORDER BY SUM(a.total_pages) DESC
获取使用的页面(8K 块)最多的表。
【讨论】:
SELECT OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS TableName, ... 的架构名称
在 SQL Server 2008 中,您也可以只运行按 Top Tables 划分的标准磁盘使用情况报告。这可以通过右键单击数据库,选择 Reports->Standard Reports 并选择所需的报告来找到。
【讨论】:
此查询有助于查找您正在连接的最大表。
SELECT TOP 1 OBJECT_NAME(OBJECT_ID) TableName, st.row_count
FROM sys.dm_db_partition_stats st
WHERE index_id < 2
ORDER BY st.row_count DESC
【讨论】:
您也可以使用以下代码:
USE AdventureWork
GO
CREATE TABLE #GetLargest
(
table_name sysname ,
row_count INT,
reserved_size VARCHAR(50),
data_size VARCHAR(50),
index_size VARCHAR(50),
unused_size VARCHAR(50)
)
SET NOCOUNT ON
INSERT #GetLargest
EXEC sp_msforeachtable 'sp_spaceused ''?'''
SELECT
a.table_name,
a.row_count,
COUNT(*) AS col_count,
a.data_size
FROM #GetLargest a
INNER JOIN information_schema.columns b
ON a.table_name collate database_default
= b.table_name collate database_default
GROUP BY a.table_name, a.row_count, a.data_size
ORDER BY CAST(REPLACE(a.data_size, ' KB', '') AS integer) DESC
DROP TABLE #GetLargest
【讨论】:
如果您使用的是 Sql Server Management Studio 2008,您可以在对象资源管理器详细信息窗口中查看某些数据字段。只需浏览并选择表文件夹。在详细信息视图中,您可以右键单击列标题并将字段添加到“报告”。如果您使用 SSMS 2008 express,您的里程可能会有所不同。
【讨论】:
我发现这个查询在 SqlServerCentral 中也很有帮助,这里是原始帖子的链接
select name=object_schema_name(object_id) + '.' + object_name(object_id)
, rows=sum(case when index_id < 2 then row_count else 0 end)
, reserved_kb=8*sum(reserved_page_count)
, data_kb=8*sum( case
when 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 )
, index_kb=8*(sum(used_page_count)
- sum( case
when 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 )
)
, unused_kb=8*sum(reserved_page_count-used_page_count)
from sys.dm_db_partition_stats
where object_id > 1024
group by object_id
order by
rows desc
在我的数据库中,他们在这个查询和第一个答案之间给出了不同的结果。
希望有人觉得有用
【讨论】:
@marc_s 的回答非常棒,我已经使用了几年了。但是,我注意到该脚本遗漏了某些列存储索引中的数据并且没有显示完整的图片。例如。当您对脚本执行SUM(TotalSpace) 并将其与 Management Studio 中的总空间数据库属性进行比较时,在我的情况下数字不匹配(Management Studio 显示更大的数字)。我修改了脚本来解决这个问题,并对其进行了一些扩展:
select
tables.[name] as table_name,
schemas.[name] as schema_name,
isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown') as database_name,
sum(allocation_units.total_pages) * 8 as total_space_kb,
cast(round(((sum(allocation_units.total_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as total_space_mb,
sum(allocation_units.used_pages) * 8 as used_space_kb,
cast(round(((sum(allocation_units.used_pages) * 8) / 1024.00), 2) as numeric(36, 2)) as used_space_mb,
(sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8 as unused_space_kb,
cast(round(((sum(allocation_units.total_pages) - sum(allocation_units.used_pages)) * 8) / 1024.00, 2) as numeric(36, 2)) as unused_space_mb,
count(distinct indexes.index_id) as indexes_count,
max(dm_db_partition_stats.row_count) as row_count,
iif(max(isnull(user_seeks, 0)) = 0 and max(isnull(user_scans, 0)) = 0 and max(isnull(user_lookups, 0)) = 0, 1, 0) as no_reads,
iif(max(isnull(user_updates, 0)) = 0, 1, 0) as no_writes,
max(isnull(user_seeks, 0)) as user_seeks,
max(isnull(user_scans, 0)) as user_scans,
max(isnull(user_lookups, 0)) as user_lookups,
max(isnull(user_updates, 0)) as user_updates,
max(last_user_seek) as last_user_seek,
max(last_user_scan) as last_user_scan,
max(last_user_lookup) as last_user_lookup,
max(last_user_update) as last_user_update,
max(tables.create_date) as create_date,
max(tables.modify_date) as modify_date
from
sys.tables
left join sys.schemas on schemas.schema_id = tables.schema_id
left join sys.indexes on tables.object_id = indexes.object_id
left join sys.partitions on indexes.object_id = partitions.object_id and indexes.index_id = partitions.index_id
left join sys.allocation_units on partitions.partition_id = allocation_units.container_id
left join sys.dm_db_index_usage_stats on tables.object_id = dm_db_index_usage_stats.object_id and indexes.index_id = dm_db_index_usage_stats.index_id
left join sys.dm_db_partition_stats on tables.object_id = dm_db_partition_stats.object_id and indexes.index_id = dm_db_partition_stats.index_id
group by schemas.[name], tables.[name], isnull(db_name(dm_db_index_usage_stats.database_id), 'Unknown')
order by 5 desc
希望它对某人有所帮助。 该脚本针对具有数百个不同表、索引和架构的大型 TB 级数据库进行了测试。
【讨论】: