diff --git a/src/PlanViewer.App/Controls/QueryStoreGridControl.axaml.cs b/src/PlanViewer.App/Controls/QueryStoreGridControl.axaml.cs
index 1769992..077c394 100644
--- a/src/PlanViewer.App/Controls/QueryStoreGridControl.axaml.cs
+++ b/src/PlanViewer.App/Controls/QueryStoreGridControl.axaml.cs
@@ -462,9 +462,9 @@ private void OnWaitStatsCollapsedChanged(object? sender, bool collapsed)
if (!collapsed && _slicerStartUtc.HasValue && _slicerEndUtc.HasValue)
{
- // Re-fetch wait stats when expanding
- var cts = new CancellationTokenSource();
- _ = FetchWaitStatsAsync(_slicerStartUtc.Value, _slicerEndUtc.Value, cts.Token);
+ // Re-fetch wait stats when expanding — reuse the shared CTS
+ var ct = _fetchCts?.Token ?? CancellationToken.None;
+ _ = FetchWaitStatsAsync(_slicerStartUtc.Value, _slicerEndUtc.Value, ct);
}
}
diff --git a/src/PlanViewer.Core/Services/QueryStoreService.cs b/src/PlanViewer.Core/Services/QueryStoreService.cs
index dec2e83..aeb78f5 100644
--- a/src/PlanViewer.Core/Services/QueryStoreService.cs
+++ b/src/PlanViewer.Core/Services/QueryStoreService.cs
@@ -473,14 +473,13 @@ JOIN sys.query_store_runtime_stats_interval rsi
return rows;
}
- ///
- /// Per-plan wait stats aggregated for a time range, grouped by plan_id + category.
- /// WaitRatio = SUM(total_query_wait_time_ms) / sum(rs.avg_duration*rs.count_executions)
- /// ==> May be challenged. But at the detail level we use the plan duration use query stats.
- /// So it is different from the other wait ratio calculation, which is based on the interval duration.
- /// We can consider to align them in the future if needed.
- ///
- public static async Task> FetchPlanWaitStatsAsync(
+ ///
+ /// Per-plan wait stats aggregated for a time range, grouped by plan_id + category.
+ /// WaitRatio = SUM(total_query_wait_time_ms) / SUM(avg_duration * count_executions).
+ /// This differs from the global/hourly WTR (which divides by wall-clock interval) because
+ /// at plan level we measure what fraction of actual execution time was spent waiting.
+ ///
+ public static async Task> FetchPlanWaitStatsAsync(
string connectionString, DateTime startUtc, DateTime endUtc,
CancellationToken ct = default)
{