From 679eb9cf14370adaa795a85fc71e31e2f6e779f1 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Tue, 7 Apr 2026 11:46:12 -0400 Subject: [PATCH] Refine Rule 3 (Serial Plan): TRIVIAL, 0ms, severity demotion - Suppress for TRIVIAL optimization level (can't go parallel anyway) - Suppress for 0ms actual elapsed time - Demote to Info unless user explicitly forced serial (MAXDOP 1 / hint) Ported from PerformanceStudio #178 round 2 feedback. Co-Authored-By: Claude Opus 4.6 (1M context) --- Dashboard/Services/PlanAnalyzer.cs | 11 ++++++++--- Lite/Services/PlanAnalyzer.cs | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Dashboard/Services/PlanAnalyzer.cs b/Dashboard/Services/PlanAnalyzer.cs index 5c9e8c9f..4c2e59b6 100644 --- a/Dashboard/Services/PlanAnalyzer.cs +++ b/Dashboard/Services/PlanAnalyzer.cs @@ -38,9 +38,12 @@ public static void Analyze(ParsedPlan plan) private static void AnalyzeStatement(PlanStatement stmt) { // Rule 3: Serial plan with reason - // Skip trivial statements (e.g., variable assignments, constant scans) — not worth warning about + // Skip: trivial cost (< 0.01), TRIVIAL optimization (can't go parallel anyway), + // and 0ms actual elapsed time (not worth flagging). if (!string.IsNullOrEmpty(stmt.NonParallelPlanReason) - && stmt.StatementSubTreeCost >= 0.01) + && stmt.StatementSubTreeCost >= 0.01 + && stmt.StatementOptmLevel != "TRIVIAL" + && !(stmt.QueryTimeStats != null && stmt.QueryTimeStats.ElapsedTimeMs == 0)) { var reason = stmt.NonParallelPlanReason switch { @@ -52,11 +55,13 @@ private static void AnalyzeStatement(PlanStatement stmt) _ => stmt.NonParallelPlanReason }; + var isExplicit = stmt.NonParallelPlanReason is "MaxDOPSetToOne" or "QueryHintNoParallelSet"; + stmt.PlanWarnings.Add(new PlanWarning { WarningType = "Serial Plan", Message = $"Query running serially: {reason}.", - Severity = PlanWarningSeverity.Warning + Severity = isExplicit ? PlanWarningSeverity.Warning : PlanWarningSeverity.Info }); } diff --git a/Lite/Services/PlanAnalyzer.cs b/Lite/Services/PlanAnalyzer.cs index 8308aafc..7f944295 100644 --- a/Lite/Services/PlanAnalyzer.cs +++ b/Lite/Services/PlanAnalyzer.cs @@ -38,9 +38,12 @@ public static void Analyze(ParsedPlan plan) private static void AnalyzeStatement(PlanStatement stmt) { // Rule 3: Serial plan with reason - // Skip trivial statements (e.g., variable assignments, constant scans) — not worth warning about + // Skip: trivial cost (< 0.01), TRIVIAL optimization (can't go parallel anyway), + // and 0ms actual elapsed time (not worth flagging). if (!string.IsNullOrEmpty(stmt.NonParallelPlanReason) - && stmt.StatementSubTreeCost >= 0.01) + && stmt.StatementSubTreeCost >= 0.01 + && stmt.StatementOptmLevel != "TRIVIAL" + && !(stmt.QueryTimeStats != null && stmt.QueryTimeStats.ElapsedTimeMs == 0)) { var reason = stmt.NonParallelPlanReason switch { @@ -52,11 +55,13 @@ private static void AnalyzeStatement(PlanStatement stmt) _ => stmt.NonParallelPlanReason }; + var isExplicit = stmt.NonParallelPlanReason is "MaxDOPSetToOne" or "QueryHintNoParallelSet"; + stmt.PlanWarnings.Add(new PlanWarning { WarningType = "Serial Plan", Message = $"Query running serially: {reason}.", - Severity = PlanWarningSeverity.Warning + Severity = isExplicit ? PlanWarningSeverity.Warning : PlanWarningSeverity.Info }); }