Skip to content

Commit e668b76

Browse files
Sync PlanAnalyzer and BenefitScorer from PerformanceStudio (Apr 9-16)
Port PS PRs #216, #217, #219, #224, #229, #230, #231 to PM. PlanAnalyzer changes: - Rule 5: Suppress for Key Lookups (point lookups mislead per-execution estimates) - Rule 8: Enhanced parallel skew with batch mode sort detection and practical context - Rule 9: Large memory grant shows top 3 consumers sorted by row count - Rule 10: Key lookup overhaul — show output columns, check predicate filtering, softer advice - Rules 11/12/29: Suppress on 0-execution nodes (operator never ran) - Rule 11: I/O wait severity elevation when scan hits disk - Rule 24: FormatNodeRef helper includes object name for data access operators - Rule 26: Suppress when row goal prediction was correct, specific cause detection - Wait stats: DescribeWaitType with full wait type coverage, multi-wait summary - New helpers: GetWaitLabel, HasSignificantIoWaits, IdentifyRowGoalCause, FormatNodeRef - GetOperatorOwnElapsedMs changed to internal for BenefitScorer access BenefitScorer (new file): - Stage 1: MaxBenefitPercent for operator-level rules (filter, spill, lookup, etc.) - Stage 2: Wait stats benefit scoring with parallel allocation (Joe's formula) PlanModels additions: - MaxBenefitPercent and ActionableFix on PlanWarning - WaitBenefit class and WaitBenefits list on PlanStatement Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a88572c commit e668b76

6 files changed

Lines changed: 1900 additions & 77 deletions

File tree

Dashboard/Models/PlanModels.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public class PlanStatement
6161
public SetOptionsInfo? SetOptions { get; set; }
6262
public List<PlanParameter> Parameters { get; set; } = new();
6363
public List<WaitStatInfo> WaitStats { get; set; } = new();
64+
public List<WaitBenefit> WaitBenefits { get; set; } = new();
6465
public QueryTimeInfo? QueryTimeStats { get; set; }
6566

6667
// Wave 2: MaxQueryMemory + QueryPlan-level warnings
@@ -370,6 +371,17 @@ public class PlanWarning
370371
public string Message { get; set; } = "";
371372
public PlanWarningSeverity Severity { get; set; }
372373
public SpillDetail? SpillDetails { get; set; }
374+
375+
/// <summary>
376+
/// Maximum percentage of elapsed time that could be saved by addressing this finding.
377+
/// null = not quantifiable, 0 = calculated as negligible.
378+
/// </summary>
379+
public double? MaxBenefitPercent { get; set; }
380+
381+
/// <summary>
382+
/// Short actionable fix suggestion (e.g., "Add INCLUDE (columns) to index").
383+
/// </summary>
384+
public string? ActionableFix { get; set; }
373385
}
374386

375387
public enum PlanWarningSeverity { Info, Warning, Critical }
@@ -433,6 +445,13 @@ public class PlanParameter
433445
public string? RuntimeValue { get; set; }
434446
}
435447

448+
public class WaitBenefit
449+
{
450+
public string WaitType { get; set; } = "";
451+
public double MaxBenefitPercent { get; set; }
452+
public string Category { get; set; } = "";
453+
}
454+
436455
public class WaitStatInfo
437456
{
438457
public string WaitType { get; set; } = "";

0 commit comments

Comments
 (0)