Sql-Server

更新 sys.objects 的統計資訊

  • April 15, 2017

我正在處理一個查詢,以將在任何級別上直接或間接依賴的所有數據庫對像都提供給一個名為 的表dbo.tblborder,該表在很大程度上依賴於該表。

但是,這個問題特別與這個查詢的查詢計劃有關,因為我在查詢計劃(在不同的排序運算符中)看到了兩種類型的警告,一種與溢出到 tempDB 有關,另一種與轉換有關的警告數據類型和基數估計。

查詢和查詢計劃在圖片之後更進一步。

問題

在處理系統對象時,如何找出需要更新統計資訊的對象?

或者,如何擺脫查詢計劃的這個警告?

關於數據類型轉換,我能做些什麼來避免這種情況以及基數估計問題嗎?

一些跟踪標誌可能嗎?

它是一個 600GB 的數據庫,我想查找特定表上的所有依賴項,僅第一級就顯示了 325 個對象,但這不是我每天都會執行的查詢。我有興趣清除這些警告,但這不是生死攸關的問題。

資訊

關於 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

這是此查詢的查詢計劃

以這種方式更新統計資訊後(來自如何更新數據庫系統表的統計資訊):

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

與 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非常好,但似乎並沒有完全解決我的問題,加上基數估計警告沒有解決。

您看到的警告很可能來自 sys.sysdepends 視圖。

如果您使用

EXEC sys.sp_helptext @objname = N'sys.sysdepends'

該定義有一堆皈依者和其他廢話。

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  

另一方面,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$  

sys.sysdepends 的視圖定義在單獨查詢時會導致相同的警告

SELECT *
FROM  sys.sysdepends  

一般來說,如果你想控制數據類型和索引,並在引用系統視圖或表時有一些性能調整能力,最好的辦法是先將它們轉儲到臨時表中。

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