Note: this version of the stored procedure takes a plan_handle as a parameter rather than a plan_id for the query store.
CREATE OR ALTER PROCEDURE sasquatch__xfer_one_plan_stats_T8666 @plan_handle VARBINARY(64) AS /* stored procedure based on work explained in the following blog post https://sql-sasquatch.blogspot.com/2018/06/harvesting-sql-server-trace-flag-8666.html supply a plan_handle and if trace flag 8666 was enabled at system level or session when plan was compiled UPDATE STATISTICS commands for each of the stats used to compile the plan will be generated */ DECLARE @startdb NVARCHAR(256), @db NVARCHAR(256), @schema NVARCHAR(256), @table NVARCHAR(256), @stats NVARCHAR(256), @cmd NVARCHAR(MAX); SET @startdb = DB_NAME(); DROP TABLE IF EXISTS #plan; CREATE TABLE #plan(planXML XML); INSERT INTO #plan SELECT CONVERT(XML, query_plan) planXML FROM sys.dm_exec_query_plan(@plan_handle); ;WITH XMLNAMESPACES(default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') SELECT DbName.DbName_Node.value('@FieldValue','NVarChar(128)') dbName, SchemaName.SchemaName_Node.value('@FieldValue','NVarChar(128)') schemaName, TableName.TableName_Node.value('@FieldValue','NVarChar(128)') tableName, StatsName_Node.value('@FieldValue','NVarChar(128)') statName, CONVERT(VARBINARY(MAX), NULL) [stats_stream], CONVERT(BIGINT, NULL) [rowcount], CONVERT(BIGINT, NULL) [pagecount] INTO #QO_stats FROM #plan qsp CROSS APPLY qsp.planXML.nodes(N'//InternalInfo/EnvColl/Recompile') AS Recomp(Recomp_node) CROSS APPLY Recomp.Recomp_Node.nodes(N'Field[@FieldName="wszDb"]') AS DbName(DbName_Node) CROSS APPLY Recomp.Recomp_Node.nodes(N'Field[@FieldName="wszSchema"]') AS SchemaName(SchemaName_Node) CROSS APPLY Recomp.Recomp_Node.nodes(N'Field[@FieldName="wszTable"]') AS TableName(TableName_Node) CROSS APPLY Recomp.Recomp_Node.nodes(N'ModTrackingInfo') AS [Table](Table_Node) CROSS APPLY Table_Node.nodes(N'Field[@FieldName="wszStatName"]') AS [Stats](StatsName_Node) OPTION (MAXDOP 1); CREATE TABLE #one_stat ([stats_stream] VARBINARY(MAX), [rowcount] BIGINT, [pagecount] BIGINT); WHILE EXISTS (SELECT TOP 1 1 FROM #QO_stats WHERE [stats_stream] IS NULL) BEGIN SELECT TOP 1 @db = dbName, @schema = schemaName, @table = tableName, @stats = statName FROM #QO_stats WHERE [stats_stream] IS NULL ORDER BY dbName, schemaName, tableName, statName; SET @cmd = N'USE ' + @db + N' DBCC SHOW_STATISTICS(''' + @schema + N'.' + @table + N''', ' + @stats + N') WITH STATS_STREAM, NO_INFOMSGS' INSERT INTO #one_stat EXEC (@cmd); UPDATE #QO_stats SET [stats_stream] = os.[stats_stream], [rowcount] = os.[rowcount], [pagecount] = os.[pagecount] FROM #one_stat os WHERE @db = #QO_stats.dbName AND @schema = #QO_stats.schemaName AND @table = #QO_stats.tableName AND @stats = #QO_stats.statName; TRUNCATE TABLE #one_stat; END SELECT N'USE ' + qo.dbName + N' UPDATE STATISTICS ' + qo.schemaName + N'.' + qo.tableName + N'(' + qo.statName + N') WITH ' + CASE WHEN qo.[pagecount] IS NULL THEN '' ELSE N'PAGECOUNT = ' + CONVERT(NVARCHAR(20), qo.[pagecount]) + N', ' END + CASE WHEN qo.[rowcount] IS NULL THEN '' ELSE N'ROWCOUNT = ' + CONVERT(NVARCHAR(20), qo.[rowcount]) + N', ' END + N'STATS_STREAM = ' + CONVERT(NVARCHAR(MAX), qo.[stats_stream], 1) FROM #QO_stats qo; EXEC (N'USE ' + @startDB); /* 20181206 */
No comments:
Post a Comment