A plan analysis fix from PerformanceStudio (PS) that PerformanceMonitor (PM) still needs. It comes from PS PR #608, which merged after the PS-to-PM sync in #4511 was finished.
Summary
Rule 33 (PlanAnalyzer.cs:1223) looks at scans on tables of 100,000 rows or more. It warns when the estimate matches one of the optimizer's fixed guesses. DetectCeGuess (PlanAnalyzer.cs:2998) picks the label for the warning. Three of its five labels name the wrong predicate. The other two are incomplete or wrong for some CE versions.
| Estimate |
PM label today |
What produces it |
| 30% |
equality guess |
An inequality such as a > 5, in every CE version. |
| 10% |
inequality guess |
One column compared with another, in every CE version. From CE 130, also an equality on an expression such as ABS(a) = 5. |
| 9% |
LIKE/BETWEEN guess |
BETWEEN or a two-sided range. From CE 120, also LIKE. Under CE 70, also two inequalities on different columns. |
| 16.4% |
compound predicate guess |
From CE 120 only: two inequalities on different columns, or a range on variables or on an expression. Under CE 70 the same predicates give 9%. |
| 1% |
multi-inequality guess |
Under CE 70 only: two 10% guesses multiplied, for example a = b AND c = d. No inequality gives 1%. CE 120 and later give 3.16% for those predicates. |
DetectCeGuess also never checks for the equality guess, and it never sees the CE version. So PM can report a band that the plan's estimator does not have.
PerformanceStudio
erikdarlingdata/PerformanceStudio@1964013 (erikdarlingdata/PerformanceStudio#608) rewrites DetectCeGuess after PS measured each guess again. The measurements ran on SQL Server 2025 on a 100,000-row heap with no statistics. CE 70 used FORCE_LEGACY_CARDINALITY_ESTIMATION, and CE 120 to 170 used the compatibility level. The PS pull request lists the row counts for each predicate.
The new DetectCeGuess differs from PM's in four ways:
- It takes the statement's
CardinalityEstimationModelVersion. A band that the estimator does not have is not reported. A plan with no version can match any band.
- Its labels follow the "What produces it" column above.
- It detects the equality guess, which depends on the row count. The guess is the square root of the row count from CE 120, and the row count to the power 0.75 under CE 70. The match tolerance is 1%.
- The 100,000-row minimum is a named constant,
CeGuessMinTableRows, with a comment that says why. If the table is smaller, the equality guess lands on the fixed bands. At 100,000 rows it is 0.3% (CE 120 and later) or 5.6% (CE 70), and it falls as the table grows.
An equality estimate from real statistics can also land within 1% of the square root of the row count. The warning text already says that the optimizer "may be using" a default guess.
Port
Replace DetectCeGuess (PlanAnalyzer.cs:2998 to 3013) with the PS version. Pass stmt.CardinalityEstimationModelVersion at the call site (PlanAnalyzer.cs:1230). The variable stmt is already in scope there, and PM already parses the CE version (ShowPlanParser.cs:599 and 667).
PM already has the 100,000-row minimum, as the literal 100_000 at PlanAnalyzer.cs:1224. The equality check depends on it, so it must stay. We recommend the named constant and the comment from PS, because the next reader must know why that number matters. Update the comment at PlanAnalyzer.cs:1219 to 1222, which repeats the old labels.
The rule number and the warning type ("Estimated Plan CE Guess") do not change. No PM test names the old labels. The PS tests are in CeGuessDetectionTests (tests/PlanViewer.Core.Tests). Every estimate in them is a value that SQL Server wrote in the PS measurements. Size S.
At 4c6dfe10. dev has no later change to PerformanceMonitor.PlanAnalysis.
A plan analysis fix from PerformanceStudio (PS) that PerformanceMonitor (PM) still needs. It comes from PS PR #608, which merged after the PS-to-PM sync in #4511 was finished.
Summary
Rule 33 (
PlanAnalyzer.cs:1223) looks at scans on tables of 100,000 rows or more. It warns when the estimate matches one of the optimizer's fixed guesses.DetectCeGuess(PlanAnalyzer.cs:2998) picks the label for the warning. Three of its five labels name the wrong predicate. The other two are incomplete or wrong for some CE versions.a > 5, in every CE version.ABS(a) = 5.a = b AND c = d. No inequality gives 1%. CE 120 and later give 3.16% for those predicates.DetectCeGuessalso never checks for the equality guess, and it never sees the CE version. So PM can report a band that the plan's estimator does not have.PerformanceStudio
erikdarlingdata/PerformanceStudio@1964013 (erikdarlingdata/PerformanceStudio#608) rewrites
DetectCeGuessafter PS measured each guess again. The measurements ran on SQL Server 2025 on a 100,000-row heap with no statistics. CE 70 usedFORCE_LEGACY_CARDINALITY_ESTIMATION, and CE 120 to 170 used the compatibility level. The PS pull request lists the row counts for each predicate.The new
DetectCeGuessdiffers from PM's in four ways:CardinalityEstimationModelVersion. A band that the estimator does not have is not reported. A plan with no version can match any band.CeGuessMinTableRows, with a comment that says why. If the table is smaller, the equality guess lands on the fixed bands. At 100,000 rows it is 0.3% (CE 120 and later) or 5.6% (CE 70), and it falls as the table grows.An equality estimate from real statistics can also land within 1% of the square root of the row count. The warning text already says that the optimizer "may be using" a default guess.
Port
Replace
DetectCeGuess(PlanAnalyzer.cs:2998to3013) with the PS version. Passstmt.CardinalityEstimationModelVersionat the call site (PlanAnalyzer.cs:1230). The variablestmtis already in scope there, and PM already parses the CE version (ShowPlanParser.cs:599and667).PM already has the 100,000-row minimum, as the literal
100_000atPlanAnalyzer.cs:1224. The equality check depends on it, so it must stay. We recommend the named constant and the comment from PS, because the next reader must know why that number matters. Update the comment atPlanAnalyzer.cs:1219to1222, which repeats the old labels.The rule number and the warning type ("Estimated Plan CE Guess") do not change. No PM test names the old labels. The PS tests are in
CeGuessDetectionTests(tests/PlanViewer.Core.Tests). Every estimate in them is a value that SQL Server wrote in the PS measurements. Size S.At
4c6dfe10.devhas no later change toPerformanceMonitor.PlanAnalysis.