更新 sys.objects 的统计信息

Mar*_*lli 5 sql-server statistics system-tables sql-server-2014 cardinality-estimates

我正在处理一个查询,将所有直接或间接依赖于任何级别的数据库对象提供给一个名为 的表dbo.tblborder,该表严重依赖。

但是,这个问题特别与此查询的查询计划有关,因为我在查询计划中看到警告(在不同的排序运算符中)两种类型的警告,一种与溢出到 tempDB 相关,另一种与转换相关的警告数据类型和基数估计。

查询和查询计划进一步向下,在图片之后。

问题

在处理系统对象时,如何找出需要更新统计信息的对象?

否则,如何摆脱查询计划上的这个警告?

关于数据类型转换,我可以做些什么来避免这种情况以及基数估计问题?

也许是一些跟踪标志?

它是一个 600GB 的数据库,我想找到特定表上的所有依赖项,仅第一级就显示了 325 个对象,但这不是我每天都会运行的查询。我对清除这些警告很感兴趣,但这不是生死攸关的问题。

信息

第 1 张关于 tempdb 溢出警告的图片:

tempdb 溢出警告图片

关于 tempdb 溢出警告的第二张图片:

在此处输入图片说明

第三个警告 - 与数据类型转换相关,可能会影响基数估计

在此处输入图片说明

;WITH Radhe AS (

            SELECT DISTINCT 
            s2.object_id, 
            Name=SCHEMA_NAME(S2.schema_id) + '.' + S2.Name, 
            ObjectType = S2.Type,
            DependsOn = s1.object_id,
            DependsOn_Name=SCHEMA_NAME(S1.schema_id) + '.' + S1.Name,  
            0 as Level

            FROM sys.sysdepends DP

            INNER JOIN sys.objects S1 
                    ON S1.object_id = DP.DepID

            INNER JOIN sys.objects S2 
                    ON S2.object_id = DP.ID

            WHERE S1.object_id = OBJECT_ID('DBO.tblborder')

            UNION ALL


            SELECT  
            s2.object_id, 
            Name=SCHEMA_NAME(S2.schema_id) + '.' + S2.Name, 
            ObjectType = S2.Type,
            DependsOn = s1.object_id,
            DependsOn_Name=s1.Name,  
            Level + 1 

            FROM sys.sysdepends DP

            INNER JOIN Radhe S1 
                       ON S1.object_id = DP.ID

            INNER JOIN sys.objects S2 
                       ON S2.object_id = DP.DepID

            WHERE Level < 100
              AND S1.object_id <> S2.object_id
              AND S2.object_id <> OBJECT_ID('DBO.tblborder')

)

SELECT DISTINCT * 
FROM Radhe
ORDER BY LEVEL DESC, DependsOn_Name
Run Code Online (Sandbox Code Playgroud)

这是此查询的查询计划

以这种方式更新统计信息后(来自如何更新数据库系统表的统计信息):

DECLARE @TSql NVARCHAR(MAX) = ''
SELECT @TSql = @TSql +  'UPDATE STATISTICS sys.' + o.name + ' WITH FULLSCAN;' + CHAR(13) + CHAR(10)
FROM sys.objects o
WHERE o.type in ('S')
ORDER BY o.name

--Verify/test commands.
PRINT @TSql
Run Code Online (Sandbox Code Playgroud)

与 tempdb 溢出相关的警告仍然存在,但是,它们已按照下图进行了更改:

在此处输入图片说明

但是,对于以下警告没有说或解决任何问题:

表达式中的类型转换 (CONVERT(bigint,[Bocss2].[sys].[sysobjvalues].[value],0)) 可能会影响查询计划选择中的“CardinalityEstimate”,表达式中的类型转换 (CONVERT(bigint,[Bocss2] .[sys].[sysobjvalues].[value],0)) 可能会影响查询计划选择中的“CardinalityEstimate”

相关的Q&A How to update statistics for a database's system tables很好,但是这里好像没有完全解决我的问题,加上没有解决基数估计警告。

Eri*_*ing 5

您看到的警告很可能来自 sys.sysdepends 视图。

如果您使用脚本编写它

EXEC sys.sp_helptext @objname = N'sys.sysdepends'
Run Code Online (Sandbox Code Playgroud)

该定义有一堆转换和其他胡说八道。

CREATE VIEW sys.sysdepends AS  
 SELECT  
  id = object_id,  
  depid = referenced_major_id,  
  number = convert(smallint,  
   case when objectproperty(object_id, 'isprocedure') = 1 then 1 else column_id end),  
  depnumber = convert(smallint, referenced_minor_id),  
  status = convert(smallint, is_select_all * 2 + is_updated * 4 + is_selected * 8),  
  deptype = class,  
  depdbid = convert(smallint, 0),  
  depsiteid = convert(smallint, 0),  
  selall = is_select_all,  
  resultobj = is_updated,  
  readobj = is_selected  
 FROM sys.sql_dependencies  
 WHERE class < 2  
 UNION ALL  
 SELECT  -- blobtype dependencies  
  id = object_id, depid = object_id,  
  number = convert(smallint, column_id), depnumber = convert(smallint, type_column_id),  
  status = convert(smallint, 0), deptype = sysconv(tinyint, 1),  
  depdbid = convert(smallint, 0), depsiteid = convert(smallint, 0),  
  selall = sysconv(bit, 0), resultobj = sysconv(bit, 0), readobj = sysconv(bit, 0)  
 FROM sys.fulltext_index_columns  
 WHERE type_column_id IS NOT NULL  
Run Code Online (Sandbox Code Playgroud)

另一方面,sys.objects 相当简单。

CREATE VIEW sys.objects AS  
 SELECT name,   
  object_id,  
  principal_id,  
  schema_id,  
  parent_object_id,  
  type,   
  type_desc,   
  create_date,   
  modify_date,  
  is_ms_shipped,  
  is_published,  
  is_schema_published  
 FROM sys.objects$  
Run Code Online (Sandbox Code Playgroud)

sys.sysdepends 的视图定义在单独查询时会导致相同的警告

SELECT *
FROM  sys.sysdepends  
Run Code Online (Sandbox Code Playgroud)

一般来说,如果您想在引用系统视图或表时控制数据类型和索引并具有一定的性能调优能力,最好的办法是先将它们转储到临时表中。