Sql-Server

sys.dm_db_stats_properties 對於一個小表來說似乎行為不端 - 如何以不同的方式獲取表的記錄數?

  • April 24, 2019

我在我的一個數據庫中有這張表:

IF OBJECT_ID('[dbo].[repl_Gender_Type]') IS NOT NULL 
DROP TABLE [dbo].[repl_Gender_Type] 
GO
CREATE TABLE [dbo].[repl_Gender_Type] ( 
[Gender_TypeID]  CHAR(1)                          NOT NULL,
[Gender_Desc]    VARCHAR(20)                      NOT NULL,
[Create_Date]    DATETIME                         NOT NULL,
[Create_Userid]  VARCHAR(20)                      NOT NULL,
CONSTRAINT   [PK__Gender__46DD686B]  PRIMARY KEY NONCLUSTERED ([Gender_TypeID] asc))

上面只有3條記錄。

即使在執行以下命令後:

update statistics dbo.repl_Gender_Type with fullscan

執行以下查詢時我沒有得到任何結果:

select SP.*
from  dbo.sysarticles A 
OUTER APPLY [sys].[dm_db_stats_properties](a.objid,1) sp
where a.objid = OBJECT_ID('dbo.repl_Gender_Type')

所以dm_db_stats_properties不跟踪小表?查找表中記錄數的解決方法是什麼?

sys.dm_db_stats_properties 在以下任何條件下返回一個空行集:

object_id 或 stats_id 為 NULL。未找到指定的對像或與表或索引視圖不對應。指定的

統計資訊 ID 與指定對象 ID 的現有統計資訊不對應。

目前使用者沒有查看統計對象的權限。當交叉應用於 sys.objects 和 sys.stats 等視圖中的行時,此行為允許安全使用 sys.dm_db_stats_properties。

我認為,以上都不對。

我喜歡在下面使用這個腳本,它來自這個問題:

sp_updatestats 與更新統計資訊

SELECT [sch].[name] + '.' + [so].[name] AS [TableName] ,
[ss].[name] AS [Statistic],
[sp].[last_updated] AS [StatsLastUpdated] ,
[sp].[rows] AS [RowsInTable] ,
[sp].[rows_sampled] AS [RowsSampled] ,
[sp].[modification_counter] AS [RowModifications]
FROM [sys].[stats] [ss]
JOIN [sys].[objects] [so] ON [ss].[object_id] = [so].[object_id]
JOIN [sys].[schemas] [sch] ON [so].[schema_id] = [sch].[schema_id]
OUTER APPLY [sys].[dm_db_stats_properties]([so].[object_id],
[ss].[stats_id]) sp
WHERE [so].[type] = 'U'
AND [sp].[modification_counter] > 0--change accordingly
ORDER BY [sp].[last_updated] DESC;

在 stats 對像中查找行數是有問題的。特別是因為每次插入、刪除或修改行時不會自動更新統計資訊。

改為使用sys.dm_db_partition_stats。它返回數據庫中每個分區的行計數資訊

SELECT Name = QUOTENAME(sch.name) + N'.' + QUOTENAME(o.name)
   , dbps.partition_number
   , dbps.row_count
   , dbps.*
FROM sys.schemas sch
   INNER JOIN sys.objects o ON sch.schema_id = o.schema_id
   INNER JOIN sys.dm_db_partition_stats dbps ON o.object_id = dbps.object_id
WHERE o.is_ms_shipped = 0
   AND (dbps.index_id = 0 OR dbps.index_id = 1); --heap or clustered indexes only

我在SQLServerScience.com上寫了一篇博文,其中顯示了與行數相關的統計屬性 DMV 的一些問題。該文章使用此查詢來獲取行數,並顯示上次更新 stats 對象的時間:

SELECT Name = QUOTENAME(sch.name) + N'.' + QUOTENAME(o.name) + N'.' + QUOTENAME(s.name)
   , ddsp.stats_id
   , last_updated = CONVERT(datetime2(1), ddsp.last_updated)
   , ddsp.rows
   , mod_count = ddsp.modification_counter
   , ddsp.unfiltered_rows
FROM sys.schemas sch
   INNER JOIN sys.objects o ON sch.schema_id = o.schema_id
   INNER JOIN sys.stats s ON o.object_id = s.object_id
   OUTER APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) ddsp
WHERE o.is_ms_shipped = 0;

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