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
3 changes: 2 additions & 1 deletion src/PlanViewer.App/Controls/PlanViewerControl.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using PlanViewer.App.Helpers;
using PlanViewer.App.Mcp;
using PlanViewer.Core.Models;
using PlanViewer.Core.Output;
using PlanViewer.Core.Services;

using AvaloniaPath = Avalonia.Controls.Shapes.Path;
Expand Down Expand Up @@ -2622,7 +2623,7 @@ static string EfficiencyColor(double pct) => pct >= 80 ? "#E4E6EB"
? (double)mg.MaxUsedMemoryKB / mg.GrantedMemoryKB * 100 : 100;
var grantColor = EfficiencyColor(grantPct);
AddRow("Memory grant",
$"{mg.GrantedMemoryKB:N0} KB granted, {mg.MaxUsedMemoryKB:N0} KB used ({grantPct:N0}%)",
$"{TextFormatter.FormatMemoryGrantKB(mg.GrantedMemoryKB)} granted, {TextFormatter.FormatMemoryGrantKB(mg.MaxUsedMemoryKB)} used ({grantPct:N0}%)",
grantColor);
if (mg.GrantWaitTimeMs > 0)
AddRow("Grant wait", $"{mg.GrantWaitTimeMs:N0}ms", "#E57373");
Expand Down
25 changes: 21 additions & 4 deletions src/PlanViewer.Core/Output/TextFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,15 @@ public static void WriteText(AnalysisResult result, TextWriter writer)
writer.WriteLine($"Runtime: {stmt.QueryTime.ElapsedTimeMs:N0}ms elapsed, {stmt.QueryTime.CpuTimeMs:N0}ms CPU");
if (stmt.MemoryGrant != null && stmt.MemoryGrant.GrantedKB > 0)
{
var grantedMB = stmt.MemoryGrant.GrantedKB / 1024.0;
var usedMB = stmt.MemoryGrant.MaxUsedKB / 1024.0;
var pctUsed = grantedMB > 0 ? usedMB / grantedMB * 100 : 0;
var pctUsed = stmt.MemoryGrant.GrantedKB > 0
? (double)stmt.MemoryGrant.MaxUsedKB / stmt.MemoryGrant.GrantedKB * 100 : 0;
var pctContext = "";
if (result.ServerContext?.MaxServerMemoryMB > 0)
{
var grantedMB = stmt.MemoryGrant.GrantedKB / 1024.0;
pctContext = $", {grantedMB / result.ServerContext.MaxServerMemoryMB * 100:N1}% of max server memory";
writer.WriteLine($"Memory grant: {grantedMB:N1} MB granted, {usedMB:N1} MB used ({pctUsed:N0}% utilized{pctContext})");
}
writer.WriteLine($"Memory grant: {FormatMemoryGrantKB(stmt.MemoryGrant.GrantedKB)} granted, {FormatMemoryGrantKB(stmt.MemoryGrant.MaxUsedKB)} used ({pctUsed:N0}% utilized{pctContext})");
}

// Expensive operators — promoted to right after memory grant.
Expand Down Expand Up @@ -323,6 +325,21 @@ private static void WriteGroupedOperatorWarnings(List<WarningResult> warnings, T
}
}

/// <summary>
/// Formats a memory value given in KB to a human-readable string.
/// Under 1,024 KB: show KB (e.g., "512 KB").
/// 1,024 KB to 1,048,576 KB: show MB with 1 decimal (e.g., "533.3 MB").
/// Over 1,048,576 KB: show GB with 2 decimals (e.g., "2.14 GB").
/// </summary>
public static string FormatMemoryGrantKB(long kb)
{
if (kb < 1024)
return $"{kb:N0} KB";
if (kb < 1024 * 1024)
return $"{kb / 1024.0:N1} MB";
return $"{kb / (1024.0 * 1024.0):N2} GB";
}

/// <summary>
/// Replaces newlines with unit separator (U+001F) so multi-line warning messages
/// survive the top-level line split in AdviceContentBuilder.Build().
Expand Down
Loading