Skip to content

Plan analysis: drop three rules PerformanceStudio removed, and show its CPU:Elapsed ratio (#4537) - #4565

Merged
erikdarlingdata merged 3 commits into
devfrom
plan-sync/4537-drop-rules
Sep 28, 2026
Merged

erikdarlingdata merged 3 commits into
devfrom
plan-sync/4537-drop-rules

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Fixes #4537
Part of #4511

Why

PerformanceStudio removed three plan-analysis rules after its rule-set review (erikdarlingdata/PerformanceStudio#215). PerformanceMonitor still ran them. The two analyzers are meant to be equivalent, so this removes them here too.

What changes

  • PlanAnalyzer:
    • removes rules 21, 25 and 31;
    • removes the helpers only they used (rule 21's CTE detector, and the wait-stats advice helpers that rules 25 and 31 called).
  • BenefitScorer: removes the rule 25 and rule 31 scoring cases.
  • The wait-stat half of erikdarlingdata/PerformanceStudio@aabbaa2 is already matched: PerformanceMonitor reads curated descriptions from Resources/WaitStats.json (WaitStatsConfig.Description), and EmitWaitStatWarnings sets no ActionableFix. That is PerformanceStudio's current shape.
  • The plan viewer's runtime summary gains the CPU:Elapsed row, as PerformanceStudio's does:
    • it sits directly after Elapsed;
    • it shows only when elapsed time is above zero;
    • it takes external-wait time out of CPU first (BenefitScorer.IsExternalWait), as PerformanceStudio does.
    • The calculation is PlanDisplayText.CpuElapsedRatio, so it can be tested without a WPF host.
  • Not ported here:

Test plan

Darling/Darling.Tests/PlanSync4537Tests.cs has seven tests:

  • Three rule-removal tests, one per removed rule. Each builds the plan shape that fired the rule on dev:

    • a CTE referenced twice;
    • a parallel plan with elapsed time well above CPU;
    • a parallel plan with CPU close to elapsed but far below its DOP potential.

    Each asserts the finding is gone. All three were RED on dev, in a detached worktree, and GREEN here. Mutation: restoring the rule 25/31 block turned both of their tests RED.

  • Four CpuElapsedRatio tests:

    • CPU 800 ms / elapsed 400 ms with no waits → 2.00;
    • the same with a 300 ms external wait → 1.25;
    • elapsed 0 → no row;
    • an external wait larger than CPU → 0.

    Mutation: removing the external-wait subtraction turned two of them RED.

  • Run: PlanSync4537Tests 7/7. The full plan-analysis class list: 238 passed, 0 failed, and 2 skipped (live PostgreSQL, run in CI).

  • Builds: Darling.Tests, PerformanceMonitor.Ui, Lite, Lite.Tests and Dashboard.Tests (Release, EnableWindowsTargeting) all have 0 warnings.

CHANGELOG

SECTION: Changed
ENTRY: - Plan analysis drops three rules that PerformanceStudio removed ([#4565]) - CTE Multiple References, Ineffective Parallelism and Parallel Wait Bottleneck are no longer reported. They guessed at what the runtime stats and wait stats already show. The plan viewer's runtime summary shows a CPU:Elapsed ratio instead, with external-wait time left out of CPU, as PerformanceStudio does.
REF: [#4565]: #4565

…ism and Parallel Wait Bottleneck rules, matching PerformanceStudio (#4537)

Rule 21 (CTE Multiple References) guessed at CTE reuse from statement text; an actual plan's own runtime stats already show where time went. Rules 25 (Ineffective Parallelism) and 31 (Parallel Wait Bottleneck) guessed at parallelism efficiency causes that the wait stats list and the runtime summary's new CPU:Elapsed ratio already show directly.
… PerformanceStudio's

Moved the CPU:Elapsed row so it sits right after Elapsed, and made its
CPU value subtract external-wait time before dividing, matching
erikdarlingdata/PerformanceStudio@28d4c74. The ratio is now computed
by a small pure helper (PlanDisplayText.CpuElapsedRatio) so it can be
pinned without a WPF host.
Adds back the three rule-removal tests (CTE Multiple References,
Parallel Wait Bottleneck, Ineffective Parallelism) alongside the four
CPU:Elapsed ratio tests, so all seven pins for this change live in one
class.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant