我有一条select语句,该语句必须连接多个表,包括sys.indexes
,sys.objects
,sys.schemas
和sys.dm_db_index_physical_stats
,以获得这样的表
这是声明:
select
db_name() as [Database],
sc.[name] as [Schema],
obj.[name] as [Table],
idx.[type_desc] as [Index Type],
idx.[name] as [Index Name],
ips.[avg_fragmentation_in_percent] as [Fragmentation Percent]
from
sys.indexes as idx
inner join
sys.objects as obj on idx.object_id = obj.object_id
inner join
sys.schemas as sc on obj.schema_id = sc.schema_id
inner join
sys.dm_db_index_physical_stats( NULL,NULL, NULL, NULL ,'LIMITED') AS ips on obj.object_id = ips.object_id
where
idx.[name] is not null
and obj.[type] = 'u' or obj.[type] = 'v'
order by
[Fragmentation Percent] desc
问题是该语句工作不正确,并且两次包含一些行(这样做像是交叉联接,但不完全是这样)。谁能指出我的错误?
感谢您的时间!
答案 0 :(得分:3)
使用CROSS_APPLY
代替INNER JOIN
。这将允许您将相关值传递给表值函数。在此处将分区号添加到结果中:
SELECT
db_name() as [Database],
sc.[name] as [Schema],
obj.[name] as [Table],
idx.[type_desc] as [Index Type],
idx.[name] as [Index Name],
ips.partition_number AS [Partition Number],
ips.[avg_fragmentation_in_percent] as [Fragmentation Percent]
FROM sys.indexes as idx
INNER JOIN sys.objects as obj on idx.object_id = obj.object_id
INNER JOIN sys.schemas as sc on obj.schema_id = sc.schema_id
CROSS APPLY sys.dm_db_index_physical_stats( DB_ID(), idx.object_id, idx.index_id, NULL ,'LIMITED') AS ips
ORDER BY [Fragmentation Percent] desc;
原始查询的错误是您没有在sys.dm_db_index_physical_stats的联接中包括index_id,并且没有为当前数据库中的对象过滤(相同的object_id可能存在于不同的数据库中)。 WHERE
子句是多余的,因此我将其删除。
出于碎片整理的目的,应排除小索引,因为这些小索引是从混合盘区中分配的,即使重新构建,也会报告高碎片。