改善 sys.dm_db_stats_properties DMV 性能不佳的问题

rus*_*ind 8 sql-server statistics dmv sql-server-2017 query-performance

我们有一些数据库有宽表COLUMNSTORE压缩(21 或 30 COLUMNS)和 2500 个分区(按日期)。该数据库中大约有 4000 个 stats 对象,其中大部分是分区表上的 INCREMENTAL 列统计信息。

sys.dm_db_stats_properties在这些数据库上运行时,这个表函数的性能极差。我们正在查看每行大约 1 秒 - 即此表函数的每次“运行”。

下面是一个简单查询生成的查询计划示例,其CROSS APPLY语法用于针对 1605 个 stats-table 组合执行此表函数。 查询计划

这里没有什么非常有帮助的 - DMV 的表现显然很差。

我目前的理论是,由于数据库中统计对象的性质,对 OPENROWSET 内部表的查询优化不佳(可能是TOP 1,这就是导致速度变慢的原因。

CREATE FUNCTION sys.dm_db_stats_properties (@object_id int, @stats_id int)
RETURNS TABLE
AS
RETURN SELECT TOP 1 -- The first row in the TVF will be the root; avoid scanning entire TVF to find any additional rows.
    object_id, -- Columns now explicit since underlying tvf has additional columns we don't want to expose for backwards compat
    stats_id,
    last_updated,
    rows,
    rows_sampled,
    steps,
    unfiltered_rows,
    modification_counter,
    persisted_sample_percent
FROM OPENROWSET(TABLE DM_DB_STATS_PROPERTIES, @object_id, @stats_id)
Run Code Online (Sandbox Code Playgroud)

但是,鉴于这sys.dm_db_stats_properties是一个 DMV,因此是不可变的,据我所知,我们无法更改它查询内部表或类似内容的方式。

此处的目标是以不占用每个数据库 3 小时的方式rows, rows_sampled, unfiltered_rows, modification_counter, last_updated获取列的值sys.dm_db_stats_properties!我们是否使用不同的 DMV 都没有关系,只要信息来源不那么准确即可。

我们已尝试重新组织所有系统表,以查看这对诸如ALTER INDEX ALL ON [Database].sys.[table to reorganize] REORGANIZE. 但是,没有观察到性能提升。

我们正在运行以下版本的 SQL Server:Microsoft SQL Server 2017 (RTM-CU18) (KB4527377) - Windows Server 2016 上的 14.0.3257.3 (X64)。兼容性级别为 140

Pau*_*ite 7

你可以得到一切,除了modification_counterDBCC SHOW_STATISTICS

DBCC SHOW_STATISTICS ( table_or_indexed_view_name , target )
WITH STAT_HEADER;
Run Code Online (Sandbox Code Playgroud)

您需要使用以下内容将其输出捕获到临时表中:

CREATE TABLE #StatHeader
(
    [Name] sysname NULL,
    Updated datetime NULL,
    [Rows] bigint NULL,
    [Rows Sampled] bigint NULL,
    Steps integer NULL,
    Density float NULL,
    [Average key length] integer NULL,
    [String Index] varchar(3) NULL,
    [Filter Expression] nvarchar(max) NULL,
    [Unfiltered Rows] bigint NULL,
    [Persisted Sample Percent] integer NULL
);

INSERT #StatHeader
EXECUTE('DBCC SHOW_STATISTICS (table, stat) WITH STAT_HEADER;');
Run Code Online (Sandbox Code Playgroud)

rowmodctron提供了一个替代修改计数器sys.sysindexes

这是一种解决方法,也是我们在提供新 DMV 之前会做的事情。这并不理想,您应该向 Microsoft 报告您看到的意外缓慢的性能。