From 6fa4ecb5138dd61e3b3a6174d1090b694f7d3c28 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Tue, 10 Mar 2026 07:48:07 -0400 Subject: [PATCH] Fix false positive parallel skew warning at DOP 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filter out thread 0 (coordinator) from skew calculation since it typically processes 0 rows in parallel operators, inflating the thread count. Raise the DOP 2 threshold from 75% to 80% — a 53/47 split is perfectly normal with only 2 worker threads. Fixes #73. Co-Authored-By: Claude Opus 4.6 --- src/PlanViewer.Core/Services/PlanAnalyzer.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/PlanViewer.Core/Services/PlanAnalyzer.cs b/src/PlanViewer.Core/Services/PlanAnalyzer.cs index 81ac926..f16e976 100644 --- a/src/PlanViewer.Core/Services/PlanAnalyzer.cs +++ b/src/PlanViewer.Core/Services/PlanAnalyzer.cs @@ -600,15 +600,19 @@ private static void AnalyzeNode(PlanNode node, PlanStatement stmt, AnalyzerConfi // Rule 8: Parallel thread skew (actual plans with per-thread stats) // Only warn when there are enough rows to meaningfully distribute across threads + // Filter out thread 0 (coordinator) which typically does 0 rows in parallel operators if (!cfg.IsRuleDisabled(8) && node.PerThreadStats.Count > 1) { - var totalRows = node.PerThreadStats.Sum(t => t.ActualRows); - var minRowsForSkew = node.PerThreadStats.Count * 1000; + var workerThreads = node.PerThreadStats.Where(t => t.ThreadId > 0).ToList(); + if (workerThreads.Count < 2) workerThreads = node.PerThreadStats; // fallback + var totalRows = workerThreads.Sum(t => t.ActualRows); + var minRowsForSkew = workerThreads.Count * 1000; if (totalRows >= minRowsForSkew) { - var maxThread = node.PerThreadStats.OrderByDescending(t => t.ActualRows).First(); + var maxThread = workerThreads.OrderByDescending(t => t.ActualRows).First(); var skewRatio = (double)maxThread.ActualRows / totalRows; - var skewThreshold = node.PerThreadStats.Count == 2 ? 0.75 : 0.50; + // At DOP 2, a 60/40 split is normal — use higher threshold + var skewThreshold = workerThreads.Count <= 2 ? 0.80 : 0.50; if (skewRatio >= skewThreshold) { var message = $"Thread {maxThread.ThreadId} processed {skewRatio:P0} of rows ({maxThread.ActualRows:N0}/{totalRows:N0}). Work is heavily skewed to one thread, so parallelism isn't helping much.";