什么是 Query Store 2017 中的“日志内存”

Jam*_*ins 4 sql-server query-store sql-server-2017

在 SQL 2017 中,除了2017添加的之外,还有一个新的执行指标“日志内存”我没有找到任何关于它的信息。

执行指标:(SQL 2017)

CPU 时间、持续时间、执行计数、逻辑读取、逻辑写入、内存消耗、物理读取、CLR 时间、并行度 (DOP)、行计数、日志内存、TempDB 内存和等待时间

我相信我了解所有其他指标是什么以及我为什么会关心。

我在几个特定时期运行了前 5 个资源消耗查询的所有指标。我记录了,现在我正在检查结果。我知道“日志内存”的(非常大)值以 KB 为单位。

指标“日志内存”究竟是什么?

编辑,收到两个答案我检查

LowlyDBA的回答表明它是来自 5 个相关领域的组合sys.query_store_runtime_stats

使用jadarnel27 在他们的回答中提供的代码来验证

我创建了数据库 '231682' 并运行了 5 个字段的测试查询,我得到的结果非常相似

231682-数据

我总结(用于=SUM()在Excel中)我的价值观,并得到1383040(字节)

我查看了查询存储,对于使用的日志内存 (KB),它显示的值为 354,058,240 (KB),这个数字要大几个数量级,与字节相比也是 KB,以字节为单位,它将是 354,058,240,000(字节)

231682-QS

我把所有字段的总数相加,只得到 1,655,236(字节)

SELECT *
FROM sys.query_store_runtime_stats qsrs
WHERE qsrs.avg_log_bytes_used > 0;
Run Code Online (Sandbox Code Playgroud)

我怀疑我的问题的答案是 SQL 2017 中的“日志内存”指标没有任何实际价值。这个小实验中显示的值是 354GB,高得不切实际。

Low*_*n M 10

如果我们查看底层对象的文档sys.query_store_runtime_stats,我们会看到它有以下描述:

  • avg_log_bytes_used - 聚合间隔内查询计划使用的数据库日志中的平均字节数。
    注意: Azure SQL 数据仓库将始终返回零 (0)。
  • last_log_bytes_used - 聚合间隔内上次执行查询计划使用的数据库日志中的字节数。
    注意: Azure SQL 数据仓库将始终返回零 (0)。
  • min_log_bytes_used - 查询计划使用的数据库日志中的最小字节数,在聚合间隔内。
    注意: Azure SQL 数据仓库将始终返回零 (0)。
  • max_log_bytes_used - 聚合间隔内查询计划使用的数据库日志中的最大字节数。
    注意: Azure SQL 数据仓库将始终返回零 (0)。
  • stdev_log_bytes_used - 聚合间隔内查询计划使用的数据库日志中字节数的标准偏差。
    注意: Azure SQL 数据仓库将始终返回零 (0)。


Jos*_*ell 6

LowlyDBA 的回答涵盖了指标的实际含义。 这个答案只是为了解释为什么 Query Store 用户界面中的数字不完全有意义。

获取一些日志数据

首先,让我们在笔记本电脑上的 SQL Server 2017 Developer Edition 上获取这些列中的数据。

创建数据库:

USE [master];
GO

CREATE DATABASE [231682];
GO
Run Code Online (Sandbox Code Playgroud)

使用非常不切实际的设置启用查询存储:

ALTER DATABASE [231682] SET QUERY_STORE = ON (INTERVAL_LENGTH_MINUTES = 1);
Run Code Online (Sandbox Code Playgroud)

做一些会产生一些事务日志使用的事情:

USE [231682];

CREATE TABLE dbo.Junk
(
    Id INT NOT NULL,
    MoreJunk NVARCHAR(MAX) NOT NULL
);

INSERT INTO dbo.Junk
    (Id, MoreJunk)
SELECT TOP 1000
    m.message_id, m.[text]
FROM sys.messages m;
Run Code Online (Sandbox Code Playgroud)

强制刷新到磁盘以防它尚未发生:

EXEC sp_query_store_flush_db;
Run Code Online (Sandbox Code Playgroud)

瞧:

SELECT 
    qsrs.avg_log_bytes_used, 
    qsrs.last_log_bytes_used, 
    qsrs.min_log_bytes_used, 
    qsrs.max_log_bytes_used, 
    qsrs.stdev_log_bytes_used
FROM sys.query_store_runtime_stats qsrs
WHERE qsrs.avg_log_bytes_used > 0;
Run Code Online (Sandbox Code Playgroud)

非零数据的结果截图

计算问题

从查询存储用户界面的角度来看,正在运行的计算如下所示:

SELECT TOP (@results_row_count)
    -- other columns
    ROUND(CONVERT(float, SUM(rs.avg_log_bytes_used*rs.count_executions))*1024,2) total_log_bytes_used,
    -- other columns
FROM sys.query_store_runtime_stats rs
    JOIN sys.query_store_plan p ON p.plan_id = rs.plan_id
    JOIN sys.query_store_query q ON q.query_id = p.query_id
    JOIN sys.query_store_query_text qt ON q.query_text_id = qt.query_text_id
WHERE NOT (rs.first_execution_time > @interval_end_time OR rs.last_execution_time < @interval_start_time)
GROUP BY p.query_id, qt.query_sql_text, q.object_id
HAVING COUNT(distinct p.plan_id) >= 1
ORDER BY total_log_bytes_used DESC
Run Code Online (Sandbox Code Playgroud)

计算中有一个错误,从字节到千字节应该除以 1,024。就目前而言,它将字节乘以 1,024,然后将它们报告为千字节 - 这使它们看起来相差了大约 1,000,000 倍。

例如,我在这里的 repro 在 1 次查询执行中产生了 346,796 字节的日志。查询存储用户界面没有显示 338 KB,而是显示 355,119,104 KB。

我已向 Microsoft 报告了此问题:查询存储“已使用的日志内存”指标计算错误