Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dashboard/Services/PlanAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@

// Rule 10: Key Lookup / RID Lookup with residual predicate
// Check RID Lookup first — it's more specific (PhysicalOp) and also has Lookup=true
if (node.PhysicalOp == "RID Lookup")
if (node.PhysicalOp.StartsWith("RID Lookup", StringComparison.OrdinalIgnoreCase))
{
var message = "RID Lookup — this table is a heap (no clustered index). SQL Server found rows via a nonclustered index but had to follow row identifiers back to unordered heap pages. Heap lookups are more expensive than key lookups because pages are not sorted and may have forwarding pointers. Add a clustered index to the table.";
if (!string.IsNullOrEmpty(node.Predicate))
Expand Down Expand Up @@ -496,7 +496,7 @@
"Leading wildcard LIKE prevents an index seek — SQL Server must scan every row. If substring search performance is critical, consider a full-text index or a trigram-based approach.",
"CASE expression in predicate" =>
"CASE expression in a predicate prevents an index seek. Rewrite using separate WHERE clauses combined with OR, or split into multiple queries.",
_ when nonSargableReason.StartsWith("Function call") =>

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Dashboard/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorDashboard.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorDashboard.Models.PlanNode, PerformanceMonitorDashboard.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)
$"{nonSargableReason} prevents an index seek. Remove the function from the column side — apply it to the parameter instead, or create a computed column with the expression and index that.",
_ =>
$"{nonSargableReason} prevents an index seek, forcing a scan."
Expand Down
2 changes: 1 addition & 1 deletion Lite/Services/PlanAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@

// Rule 10: Key Lookup / RID Lookup with residual predicate
// Check RID Lookup first — it's more specific (PhysicalOp) and also has Lookup=true
if (node.PhysicalOp == "RID Lookup")
if (node.PhysicalOp.StartsWith("RID Lookup", StringComparison.OrdinalIgnoreCase))
{
var message = "RID Lookup — this table is a heap (no clustered index). SQL Server found rows via a nonclustered index but had to follow row identifiers back to unordered heap pages. Heap lookups are more expensive than key lookups because pages are not sorted and may have forwarding pointers. Add a clustered index to the table.";
if (!string.IsNullOrEmpty(node.Predicate))
Expand Down Expand Up @@ -496,7 +496,7 @@
"Leading wildcard LIKE prevents an index seek — SQL Server must scan every row. If substring search performance is critical, consider a full-text index or a trigram-based approach.",
"CASE expression in predicate" =>
"CASE expression in a predicate prevents an index seek. Rewrite using separate WHERE clauses combined with OR, or split into multiple queries.",
_ when nonSargableReason.StartsWith("Function call") =>

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)

Check warning on line 499 in Lite/Services/PlanAnalyzer.cs

View workflow job for this annotation

GitHub Actions / build

The behavior of 'string.StartsWith(string)' could vary based on the current user's locale settings. Replace this call in 'PerformanceMonitorLite.Services.PlanAnalyzer.AnalyzeNode(PerformanceMonitorLite.Models.PlanNode, PerformanceMonitorLite.Models.PlanStatement)' with a call to 'string.StartsWith(string, System.StringComparison)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1310)
$"{nonSargableReason} prevents an index seek. Remove the function from the column side — apply it to the parameter instead, or create a computed column with the expression and index that.",
_ =>
$"{nonSargableReason} prevents an index seek, forcing a scan."
Expand Down