更新 sys.objects 的統計資訊
我正在處理一個查詢,以將在任何級別上直接或間接依賴的所有數據庫對像都提供給一個名為 的表
dbo.tblborder
,該表在很大程度上依賴於該表。但是,這個問題特別與這個查詢的查詢計劃有關,因為我在查詢計劃(在不同的排序運算符中)看到了兩種類型的警告,一種與溢出到 tempDB 有關,另一種與轉換有關的警告數據類型和基數估計。
查詢和查詢計劃在圖片之後更進一步。
問題
在處理系統對象時,如何找出需要更新統計資訊的對象?
或者,如何擺脫查詢計劃的這個警告?
關於數據類型轉換,我能做些什麼來避免這種情況以及基數估計問題嗎?
一些跟踪標誌可能嗎?
它是一個 600GB 的數據庫,我想查找特定表上的所有依賴項,僅第一級就顯示了 325 個對象,但這不是我每天都會執行的查詢。我有興趣清除這些警告,但這不是生死攸關的問題。
資訊
關於 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
一般來說,如果你想控制數據類型和索引,並在引用系統視圖或表時有一些性能調整能力,最好的辦法是先將它們轉儲到臨時表中。