我想知道如何计算文件组中每个文件消耗的数据分布,返回到存储它的索引(HEAP、CLUSTERED、NONCLUSTERED)。我的意图是定义哪个 I/O 在磁盘上的哪个位置。
我data_space_id
从 开始sys.indexes
,显示已使用、已分配的页面;和data_space_id
大小从sys.filegroups
。因此,我到达了用于将数据存储到文件组中的文件的加权(按可用空间比率?)算法生效的位置。我可以加入sys.database_files
使用data_space_id
.
从s (通过和sys.dm_allocation_unit
连接到索引)我得到;加入建议行数、使用和分配的页面,允许计算还显示每个分区的空闲内容。无法分区到文件...?object_Id
index_Id
partition_ID
sys.dm_partitions
我有一个查询,我根据文件组中每个文件的已用页面比率将 DATA 分配给 FILE,并将该比率应用于存储在文件所属文件组中的索引数据。
是否有更好的方法将表/索引数据向下钻取到文件级分配?(测量而不是计算?)
对于 indid = 0 或 indid = 1,dpages 是使用的数据页数。
对于 indid > 1,dpages 是使用的索引页数。
对于 indid = 0 或 indid = 1,used 是用于所有索引和表数据的总页数。
对于 indid > 1,used 是用于索引的页数。
对于 indid = 0 或 indid = 1,reserved 是为所有索引和表数据分配的页数。
对于 indid > 1,reserved 是为索引分配的页数。
查询语句:
Select T.Name TableName,
ISNULL(SI.Name, SI.type_desc) IndexName,
SI.index_id,
SI.type_desc,
SI.data_space_id,
S.rows Rows,
S.rowmodctr,
PIx.avg_fragmentation_in_percent,
PIx.fragment_count,
PIx.avg_fragment_size_in_pages,
CASE SI.Index_ID
WHEN 0 THEN S.dpages
WHEN 1 THEN S.dpages
END DataPages,
CASE
WHEN SI.index_id > 1
THEN S.dpages
END IndexPages,
FileUsageRatio,
S.dpages*FileUsageRatio RationedDataPagesToFile,
physical_name,
CASE SI.Index_ID
WHEN 0 THEN S.Used
WHEN 1 THEN S.Used
END UsedTableDataPages,
CASE
WHEN SI.index_id > 1
THEN S.Used
END UsedIndexPages,
CASE SI.Index_ID
WHEN 0 THEN S.reserved
WHEN 1 THEN S.reserved
END ReservedTableDataPages,
CASE
WHEN SI.index_id > 1
THEN S.Reserved
END ReservedIndexPages,
FG.name FileGroupName,
FG_SpaceUsage.FG_AllocatePages,
FG_SpaceUsage.FG_UsedPages,
FG_SpaceUsage.FG_FreePages,
FG.type_desc FileGroup_Type_desc,
OIx.singleton_lookup_count,
OIx.range_scan_count,
OIx.page_io_latch_wait_count,
OIx.page_io_latch_wait_in_ms,
OIx.page_latch_wait_count,
OIx.page_latch_wait_in_ms,
OIx.row_lock_count,
OIx.row_lock_wait_count,
OIx.row_lock_wait_in_ms,
OIx.page_lock_count,
OIx.page_lock_wait_count,
OIx.page_lock_wait_in_ms
from SYS.tables T
JOIN sys.indexes SI
ON T.Object_ID = SI.Object_ID
JOIN sys.filegroups FG
ON FG.Data_Space_ID = SI.Data_Space_ID
JOIN sys.partitions P
ON P.index_id = SI.index_id
AND P.object_id = SI.object_id
JOIN sys.allocation_units AU
ON AU.allocation_unit_id = P.partition_id
JOIN sys.dm_db_index_operational_stats(db_id(),NULL,NULL,NULL) OIx
ON OIx.index_id = P.index_id
AND OIx.object_id = P.object_id
JOIN sys.dm_db_index_physical_stats(db_id(),NULL,NULL,NULL,NULL) PIx
ON PIx.index_id = P.index_id
AND PIx.object_id = P.object_id
JOIN sys.sysindexes S
ON S.IndID = SI.Index_ID
AND S.ID = SI.Object_ID
JOIN (
SELECT Data_Space_ID, SUM(SIZE) FG_AllocatePages, SUM(UsedPages) FG_UsedPages, SUM (SIZE) - SUM(UsedPages) FG_FreePages
FROM SYS.database_files DBF
CROSS APPLY ( SELECT FILEPROPERTY(DBF.name, 'SpaceUsed') AS UsedPages) PagesUsed
GROUP BY DBF.data_space_id
) FG_SpaceUsage
ON FG_SpaceUsage.data_space_id = FG.data_space_id
JOIN
(
SELECT CTE.data_space_id, CTE.file_ID, CTE.physical_name, CTE.UsedPages*1.0/AGGREGATED.Total_UsedPages FileUsageRatio
FROM (
SELECT data_space_Id, File_ID, Physical_Name, Size, PagesUsed.UsedPages, Size- PagesUsed.UsedPages FreePages
FROM sys.database_Files DBF
CROSS APPLY ( SELECT FILEPROPERTY(DBF.name, 'SpaceUsed') AS UsedPages) PagesUsed
) CTE
JOIN
(SELECT Data_Space_ID, SUM(UsedPages) Total_UsedPages
FROM (
SELECT data_space_Id, File_ID, Physical_Name, Size, PagesUsed.UsedPages, Size-PagesUsed.UsedPages FreePages
FROM sys.database_Files DBF
CROSS APPLY ( SELECT FILEPROPERTY(DBF.name, 'SpaceUsed') AS UsedPages) PagesUsed
) CTE
GROUP BY Data_Space_ID
) AGGREGATED
ON CTE.data_space_id = AGGREGATED.data_space_id
) DataUsageRatio
ON DataUsageRatio.data_space_id = FG.data_space_id
ORDER BY TableName, Index_ID
思来想去,我做不到我想做的,比我正在做的要好。SQL Server 不会存储比它看起来更深的文件组级别的内容。从那里开始,只有内部结构;并且没有公开的方法可供查看。
背景链接:
Rob Nicholson的Round Robin 与 Proportional Fill了解James Rowland-Jones
的 -E 启动参数
要查看堆/索引与它们的数据存储在哪个文件之间的关系,请参阅我对以下问题的回答:
是否存在一种方法来确定包含多个文件的文件组中的分配单元的确切文件?
不,SQL Server 如何在可用文件中分配数据是不可配置的。