@@ -548,9 +548,9 @@ private static void AnalyzeNode(PlanNode node, PlanStatement stmt, AnalyzerConfi
548548 {
549549 // Gate: skip trivial filters based on actual stats or estimated cost
550550 bool isTrivial ;
551- long childReads = 0 ;
552551 if ( node . HasActualStats )
553552 {
553+ long childReads = 0 ;
554554 foreach ( var child in node . Children )
555555 childReads += SumSubtreeReads ( child ) ;
556556 var childElapsed = node . Children . Max ( c => c . ActualElapsedMs ) ;
@@ -571,14 +571,6 @@ private static void AnalyzeNode(PlanNode node, PlanStatement stmt, AnalyzerConfi
571571 message += $ "\n { impact } ";
572572 message += $ "\n Predicate: { predicate } ";
573573
574- // Wait stats add context — rows burned CPU/I/O/waits just to be discarded
575- if ( childReads >= 1000 )
576- {
577- var waitContext = GetTopWaitContext ( stmt . WaitStats ) ;
578- if ( waitContext != null )
579- message += $ "\n { waitContext } ";
580- }
581-
582574 node . Warnings . Add ( new PlanWarning
583575 {
584576 WarningType = "Filter Operator" ,
@@ -655,16 +647,10 @@ private static void AnalyzeNode(PlanNode node, PlanStatement stmt, AnalyzerConfi
655647 var actualDisplay = executions > 1
656648 ? $ "Actual { node . ActualRows : N0} ({ actualPerExec : N0} rows x { executions : N0} executions)"
657649 : $ "Actual { node . ActualRows : N0} ";
658- var message = $ "Estimated { node . EstimateRows : N0} vs { actualDisplay } — { factor : F0} x { direction } . { harm } ";
659-
660- var waitContext = GetTopWaitContext ( stmt . WaitStats ) ;
661- if ( waitContext != null )
662- message += $ " { waitContext } ";
663-
664650 node . Warnings . Add ( new PlanWarning
665651 {
666652 WarningType = "Row Estimate Mismatch" ,
667- Message = message ,
653+ Message = $ "Estimated { node . EstimateRows : N0 } vs { actualDisplay } — { factor : F0 } x { direction } . { harm } " ,
668654 Severity = factor >= 100 ? PlanWarningSeverity . Critical : PlanWarningSeverity . Warning
669655 } ) ;
670656 }
@@ -848,10 +834,6 @@ _ when nonSargableReason.StartsWith("Function call") =>
848834 message += $ " { details . Summary } ";
849835 message += " Check that you have appropriate indexes." ;
850836
851- var waitContext = GetTopWaitContext ( stmt . WaitStats ) ;
852- if ( waitContext != null )
853- message += $ " { waitContext } ";
854-
855837 // I/O waits specifically confirm the scan is hitting disk — elevate
856838 if ( HasSignificantIoWaits ( stmt . WaitStats ) && details . CostPct >= 50
857839 && severity != PlanWarningSeverity . Critical )
@@ -1047,10 +1029,6 @@ _ when nonSargableReason.StartsWith("Function call") =>
10471029 else
10481030 details . Add ( "Consider whether a hash or merge join would be more appropriate for this row count." ) ;
10491031
1050- var waitContext = GetTopWaitContext ( stmt . WaitStats ) ;
1051- if ( waitContext != null )
1052- details . Add ( waitContext ) ;
1053-
10541032 node . Warnings . Add ( new PlanWarning
10551033 {
10561034 WarningType = "Nested Loops High Executions" ,
@@ -1839,33 +1817,6 @@ private static bool HasSignificantIoWaits(List<WaitStatInfo> waits)
18391817 return ioMs >= 100 && pct >= 20 ;
18401818 }
18411819
1842- /// <summary>
1843- /// Returns a terse sentence describing the dominant wait type for appending
1844- /// to an existing warning message, or null if waits are negligible.
1845- /// Surfaces whatever wait type is dominant — PAGEIOLATCH, SOS_SCHEDULER_YIELD,
1846- /// CXPACKET, LCK_*, HTBUILD, EXECSYNC, IO_COMPLETION, etc.
1847- /// Threshold: top wait >= 100ms and >= 20% of total wait time.
1848- /// </summary>
1849- private static string ? GetTopWaitContext ( List < WaitStatInfo > waits )
1850- {
1851- if ( waits . Count == 0 )
1852- return null ;
1853-
1854- var totalMs = waits . Sum ( w => w . WaitTimeMs ) ;
1855- if ( totalMs == 0 )
1856- return null ;
1857-
1858- var top = waits . OrderByDescending ( w => w . WaitTimeMs ) . First ( ) ;
1859- if ( top . WaitTimeMs < 100 )
1860- return null ;
1861-
1862- var pct = ( double ) top . WaitTimeMs / totalMs * 100 ;
1863- if ( pct < 20 )
1864- return null ;
1865-
1866- return $ "Dominant wait: { top . WaitType } ({ top . WaitTimeMs : N0} ms, { pct : N0} % of total wait time).";
1867- }
1868-
18691820 private static bool AllocatesResources ( PlanNode node )
18701821 {
18711822 // Operators that get memory grants or allocate structures based on row estimates.
0 commit comments