Fir*_*gur 4 performance sql-server query query-store sql-server-2017
我正在运行查询存储以使数据库性能更好。到目前为止,它一直工作正常。当我尝试加载最后一天的热门持续时间时,我花了 26 分钟来加载屏幕。
我运行的 SQL 版本是: Microsoft SQL Server 2017 (RTM-CU27) (KB5006944) - 14.0.3421.10 (X64) Oct 14 2021 00:47:52 版权所有 (C) 2017 Microsoft Corporation Standard Edition (64-bit) on Windows Server 2019 Datacenter 10.0(内部版本 17763:)(虚拟机管理程序)
QS 中弹出查询:
/*
This query text was retrieved from showplan XML, and may be truncated.
*/
SELECT TOP (@results_row_count)
p.query_id query_id,
q.object_id object_id,
ISNULL(OBJECT_NAME(q.object_id),'') object_name,
qt.query_sql_text query_sql_text,
ROUND(CONVERT(float, SUM(rs.avg_duration*rs.count_executions))*0.001,2) total_duration,
SUM(rs.count_executions) count_executions,
COUNT(distinct p.plan_id) num_plans
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_duration DESC
Run Code Online (Sandbox Code Playgroud)
执行计划显示对象上的聚集索引扫描的成本为 96% [plan_persist_runtime_stats]
。
以下执行计划来自不同的服务器:
我没有通过脚本配置查询存储,只是通过属性配置。但在我的设置下面:
ALTER DATABASE [<DATABASE>] SET QUERY_STORE (
OPERATION_MODE = READ_WRITE,
CLEANUP_POLICY = (STALE_QUERY_THRESHOLD_DAYS = 15),
DATA_FLUSH_INTERVAL_SECONDS = 900,
MAX_STORAGE_SIZE_MB = 500,
INTERVAL_LENGTH_MINUTES = 60,
SIZE_BASED_CLEANUP_MODE = AUTO,
QUERY_CAPTURE_MODE = AUTO,
MAX_PLANS_PER_QUERY = 200
WAIT_STATS_CAPTURE_MODE = OFF
)
Run Code Online (Sandbox Code Playgroud)
如果这是 SQL Server 错误,我可以在哪里找到具有此行为的版本列表吗?
有谁知道修复是什么?
核心问题是驱动 SSMS GUI 报告的 T-SQL 代码效率不高。不幸的是,Microsoft 长期以来一直在 SSMS 的某些部分中包含低效的 T-SQL。查询存储数据模型和构成 DMV 的代码进一步加剧了问题。许多地方都存在不寻常的性能问题。例如,对于某些查询存储 DMV ,连接消除可能无法按预期工作。
我将通过对您捕获的查询文本进行最少的努力重写来支持我的批评。事实上,原始代码在我的一个生产数据库上执行需要 6 秒:
请注意,由于 runtime_stats_interval_id 的过滤器值是硬编码的,以下重写仅适用于我开发的数据库:
DECLARE
@results_row_count INT = 100,
@interval_end_time datetimeoffset = '2021-12-08 03:00:00',
@interval_start_time datetimeoffset = '2021-12-07 03:00:00';
SELECT *, qt.query_sql_text query_sql_text
FROM
(
SELECT TOP (@results_row_count)
p.query_id query_id,
q.object_id object_id,
ISNULL(OBJECT_NAME(q.object_id),'') object_name,
q.query_text_id,
ROUND(CONVERT(float, SUM(rs.avg_duration*rs.count_executions))*0.001,2) total_duration,
SUM(rs.count_executions) count_executions,
COUNT(distinct p.plan_id) num_plans
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
WHERE NOT (rs.first_execution_time > @interval_end_time OR rs.last_execution_time < @interval_start_time)
AND rs.runtime_stats_interval_id BETWEEN 11534 and 11558 -- code omitted to do this mapping but it isn't hard
GROUP BY p.query_id, q.query_text_id, q.object_id
--HAVING COUNT(distinct p.plan_id) >= 1
ORDER BY total_duration DESC
) q1
INNER JOIN sys.query_store_query_text qt ON q1.query_text_id = qt.query_text_id;
Run Code Online (Sandbox Code Playgroud)
新代码返回相同的结果,但在大约 600 毫秒内完成:
当然,以上内容对你来说并没有多大帮助。这只是一个迹象,表明 SSMS 存在缺陷,微软可以通过更改代码来解决该缺陷。我可以想到以下选项来解决您的问题:
在一个不相关的说明中,我在您的问题中注意到您没有启用等待统计信息收集。如果可能的话,我鼓励您启用它。我发现它是解决查询超时原因的强大工具。不幸的是,它确实破坏了一些 GUI 报告。
归档时间: |
|
查看次数: |
1555 次 |
最近记录: |