Sql-Server-2008-R2

sys.dm_db_index_physical_stats 錯誤

  • May 7, 2020

我正在執行一個 select 語句來檢索索引的碎片百分比並面臨以下錯誤。

   SELECT A.NAME,B.NAME,C.avg_fragmentation_in_percent 
     FROM SYS.TABLES A 
     INNER JOIN SYS.INDEXES B ON A.OBJECT_ID=B.object_id
     CROSS APPLY SYS.DM_DB_INDEX_PHYSICAL_STATS(DB_ID(),
       A.OBJECT_ID,B.INDEX_ID,0,DEFAULT) C
   WHERE B.NAME IS NOT NULL

錯誤是

消息 413,級別 16,狀態 1,行 1

內聯函式“SYS.DM_DB_INDEX_PHYSICAL_STATS”不支持相關參數或子查詢。

消息 413,級別 16,狀態 1,行 1

內聯函式“SYS.DM_DB_INDEX_PHYSICAL_STATS”不支持相關參數或子查詢。

如果您處於 80 兼容模式,則需要:

DECLARE @dbid int = DB_ID();

SELECT t.name, i.name, ps.avg_fragmentation_in_percent 
 FROM sys.tables AS t         -- why A???
 INNER JOIN sys.indexes AS i  -- why B???
   ON t.[object_id] = i.[object_id]
 CROSS APPLY sys.dm_db_index_physical_stats
   (@dbid,NULL,NULL,0,DEFAULT) AS ps -- why C???
WHERE ps.index_id = i.index_id
AND ps.[object_id] = t.[object_id]  
AND i.name IS NOT NULL;

對於 100,您需要:

SELECT t.name, i.name, ps.avg_fragmentation_in_percent 
 FROM sys.tables AS t         -- why A???
 INNER JOIN sys.indexes AS i  -- why B???
   ON t.[object_id] = i.[object_id]
 CROSS APPLY sys.dm_db_index_physical_stats
   (DB_ID(),NULL,NULL,0,DEFAULT) AS ps -- why C???
WHERE ps.index_id = i.index_id
AND ps.[object_id] = t.[object_id]  
AND i.name IS NOT NULL;

另一個答案中發布的功能看起來既方便又方便,得到了正確的答案,當您僅衡量估計成本時,它顯然是贏家,但要小心 - 當您實際繼續使用時,多語句 TVF 中有很多隱藏成本它們(在這種情況下,您不能使用內聯 TVF,原因與 OP 收到內置函式的錯誤消息相同)。以下是費用對比:

在此處輸入圖像描述

(並且只是為了顯示單個查找的成本以及沒有過濾器):

在此處輸入圖像描述

順便說一句,請注意大小寫(不要大寫系統對像或列名),使用合理的別名,並養成使用語句終止符的習慣。

引用自:https://dba.stackexchange.com/questions/141722