Cra*_*ein 6 statistics execution-plan sql-server-2016
我们最近将许多实例升级到 2016 年。因此,来自sqlpackage.exe的 SELECT 语句在某些实例上超时。
经过一些测试,我发现通过更新执行计划中显示的数据库系统表的统计信息,SELECT 停止了超时。
update statistics sys.[sysclsobjs] with fullscan
update statistics sys.[syscolpars] with fullscan
update statistics sys.[sysidxstats] with fullscan
update statistics sys.[sysiscols] with fullscan
update statistics sys.[sysobjvalues] with fullscan
Run Code Online (Sandbox Code Playgroud)
无论如何,是否可以通过标准维护包、Ola Hallengren 的脚本或其他一些过程来仅更新系统表统计信息?
08/01 更新
以下是我升级后的步骤
关于 4199 跟踪标志KB974006
-- for the instance
/*
Turn on traceflag 4199 (my understanding of this traceflag is that it disables
optimizer hotfixes in 2016
*/
-- disable automatic numa
sp_configure 'automatic soft-NUMA disabled', 1
GO
-- For each database
-- Turn on Query optimizer hotfixes
-- Turn off Legacy cardinality estimation
exec sp_MSforeachDB 'ALTER DATABASE [?] SET COMPATIBILITY_LEVEL = 130;
USE [?];
ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES = ON;
ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION = OFF;
-- update statistics for all tables, system tables are ignored
EXEC sp_MSforeachtable ''UPDATE STATISTICS [?] WITH FULLSCAN''
'
Run Code Online (Sandbox Code Playgroud)
08/02 更新
这是来自 sqlpackage.exe 的 SELECT 导致 TFS 超时
SELECT * FROM (
SELECT
SCHEMA_NAME([o].[schema_id]) AS [SchemaName],
[si].[object_id] AS [ColumnSourceId],
[o].[name] AS [ColumnSourceName],
[o].[type] AS [ColumnSourceType],
[ic].[column_id] AS [ColumnId],
[c].[name] AS [ColumnName],
[si].[index_id] AS [IndexId],
[si].[name] AS [IndexName],
[ds].[type] AS [DataspaceType],
[ds].[data_space_id] AS [DataspaceId],
[ds].[name] AS [DataspaceName],
[si].[fill_factor] AS [FillFactor],
[si].[is_padded] AS [IsPadded],
[si].[is_disabled] AS [IsDisabled],
[si].[allow_page_locks] AS [DoAllowPageLocks],
[si].[allow_row_locks] AS [DoAllowRowLocks],
[sit].[cells_per_object] AS [CellsPerObject],
[sit].[bounding_box_xmin] AS [XMin],
[sit].[bounding_box_xmax] AS [XMax],
[sit].[bounding_box_ymin] AS [YMin],
[sit].[bounding_box_ymax] AS [YMax],
[sit].[level_1_grid] AS [Level1Grid],
[sit].[level_2_grid] AS [Level2Grid],
[sit].[level_3_grid] AS [Level3Grid],
[sit].[level_4_grid] AS [Level4Grid],
[sit].[tessellation_scheme] AS [TessellationScheme],
[s].[no_recompute] AS [NoRecomputeStatistics],
[p].[data_compression] AS [DataCompressionId],
CONVERT(bit, CASE WHEN [ti].[data_space_id] = [ds].[data_space_id] THEN 1 ELSE 0 END)
AS [EqualsParentDataSpace]
FROM
[sys].[spatial_indexes] AS [si] WITH (NOLOCK)
INNER JOIN [sys].[objects] AS [o] WITH (NOLOCK) ON [si].[object_id] = [o].[object_id]
INNER JOIN [sys].[spatial_index_tessellations] [sit] WITH (NOLOCK) ON [si].[object_id] = [sit].[object_id] AND [si].[index_id] = [sit].[index_id]
INNER JOIN [sys].[data_spaces] AS [ds] WITH (NOLOCK) ON [ds].[data_space_id] = [si].[data_space_id]
INNER JOIN [sys].[index_columns] AS [ic] WITH (NOLOCK) ON [si].[object_id] = [ic].[object_id] AND [si].[index_id] = [ic].[index_id]
INNER JOIN [sys].[columns] AS [c] WITH (NOLOCK) ON [si].[object_id] = [c].[object_id] AND [ic].[column_id] = [c].[column_id]
INNER JOIN [sys].[objects] AS [o2] WITH (NOLOCK) ON [o2].[parent_object_id] = [si].[object_id]
INNER JOIN [sys].[stats] AS [s] WITH (NOLOCK) ON [o2].[object_id] = [s].[object_id] AND [s].[name] = [si].[name]
INNER JOIN [sys].[partitions] AS [p] WITH (NOLOCK) ON [p].[object_id] = [o2].[object_id] AND [p].[partition_number] = 1
LEFT JOIN [sys].[indexes] AS [ti] WITH (NOLOCK) ON [o].[object_id] = [ti].[object_id]
LEFT JOIN [sys].[tables] AS [t] WITH (NOLOCK) ON [t].[object_id] = [si].[object_id]
WHERE [si].[is_hypothetical] = 0
AND [ti].[index_id] < 2
AND OBJECTPROPERTY([o].[object_id], N'IsSystemTable') = 0
AND ([t].[is_filetable] = 0 OR [t].[is_filetable] IS NULL)
AND ([o].[is_ms_shipped] = 0 AND NOT EXISTS (SELECT *
FROM [sys].[extended_properties]
WHERE [major_id] = [o].[object_id]
AND [minor_id] = 0
AND [class] = 1
AND [name] = N'microsoft_database_tools_support'
))
) AS [_results]
Run Code Online (Sandbox Code Playgroud)
如果我不更新数据库的系统表统计信息,那么这个 SELECT 在通过 sqlpackage.exe 部署时会超时
您可以在不使用 DAC 连接的情况下“查看”系统表:
SELECT *
FROM sys.objects o
WHERE o.type = 'S'
ORDER BY o.name
Run Code Online (Sandbox Code Playgroud)
从那里,您可以构建 TSQL 命令字符串并执行它。(我sys对模式进行了硬编码。大概这永远不会改变。):
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 = 'S'
ORDER BY o.name
--Verify/test commands.
PRINT @TSql
--Uncomment and re-run when ready to proceed.
--EXEC sp_executesql @TSql
Run Code Online (Sandbox Code Playgroud)
这可以轻松地放入 SQL 代理作业的作业步骤中。我在 SQL Server 2012 w/ SP3 上对此进行了测试。我还在 SQL 2008 R2 和 SQL 2014 中运行了类似的代码。我不确定它是否在 SQL 2016 中工作 - 如果不能,请告诉我们。
其他注释当我以 [sysadmin] 身份登录时,
这些命令有效。UPDATE STATISTICS如果登录名不是 [sysadmin] 的成员,而是数据库所有者,它也可以工作。仅 [db_owner] 的成员资格是不够的。(同样,这是在 SQL 2012 w/ SP3 上。YMMV。)
| 归档时间: |
|
| 查看次数: |
2696 次 |
| 最近记录: |