sqlinsight-pro/src/SQLInsight.Web/Components/Shared/DiskTable.razor
Søren Eggert Lundsteen Olsen 7a908cc28b Explain and assess measurements for the customer
MetricAssessment rates CPU (SQL/other), batch requests, compilations
(against batches), page life expectancy (300 s per 4 GB buffer pool,
average and dips over 50 %, max server memory unset), user connections,
memory grants pending, processes blocked and disk latency as OK, Bemærk
or Reagér with a concrete next step and link, plus a plain Danish
"Hvad betyder det?" for each. Shown under every graph on the instance
page (now all eight metrics) and in the analysis, per drive in the disk
table, and in the analysis PDF.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 08:57:10 +02:00

51 lines
3 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@* Disk speed per drive: IOPS, MB/s and average latency, optionally against the normal for the same hours. *@
@if (Disks.Count == 0)
{
<p class="muted">@Empty</p>
}
else
{
<table>
<thead>
<tr>
<th>Drev</th><th class="num">Filer</th><th class="num">Læs IOPS</th><th class="num">Skriv IOPS</th>
<th class="num">Læs MB/s</th><th class="num">Skriv MB/s</th><th class="num">Gns. læs</th><th class="num">Gns. skriv</th><th>Vurdering</th>
</tr>
</thead>
<tbody>
@foreach (var d in Disks)
{
var w = d.Window;
<tr>
<td class="mono">@w.Volume</td>
<td class="num">@Files(w)</td>
<td class="num">@Display.Number(w.ReadIops ?? 0, 1)</td>
<td class="num">@Display.Number(w.WriteIops ?? 0, 1)</td>
<td class="num">@Display.Number(w.ReadMbPerSecond ?? 0, 1)</td>
<td class="num">@Display.Number(w.WriteMbPerSecond ?? 0, 1)</td>
<td class="num @(w.AverageReadMs >= 20 || Worse(w.AverageReadMs, d.Normal?.AverageReadMs) ? "bad" : "")">@Ms(w.AverageReadMs)@Normal(d.Normal?.AverageReadMs)</td>
<td class="num @(w.AverageWriteMs >= (w.DataFiles == 0 && w.LogFiles > 0 ? 5 : 20) || Worse(w.AverageWriteMs, d.Normal?.AverageWriteMs) ? "bad" : "")">@Ms(w.AverageWriteMs)@Normal(d.Normal?.AverageWriteMs)</td>
<td><AssessmentNote Assessment="SQLInsight.Reports.MetricAssessment.AssessDisk(w)" InstanceName="@InstanceName" /></td>
</tr>
}
</tbody>
</table>
<details><summary>Hvad betyder det?</summary><p>@SQLInsight.Reports.MetricAssessment.Explanation("disk.read")</p><p>@SQLInsight.Reports.MetricAssessment.Explanation("disk.write.log")</p><p>@SQLInsight.Reports.MetricAssessment.Explanation("disk.write")</p></details>
<p class="muted">Latens er gennemsnitstiden pr. læsning/skrivning set fra SQL Server (sys.dm_io_virtual_file_stats). Datafiler bør ligge under 10-20 ms, logfiler under 5 ms.@(ShowNormal ? " I parentes: det normale for samme klokkeslæt de foregående uger." : "")</p>
}
@code {
[Parameter, EditorRequired] public IReadOnlyList<SQLInsight.Reports.DiskComparison> Disks { get; set; } = [];
[Parameter] public string Empty { get; set; } = "Ingen målinger pr. drev endnu.";
[Parameter] public bool ShowNormal { get; set; }
[Parameter] public string? InstanceName { get; set; }
private static string Ms(double? value) => value is { } v ? $"{Display.Number(v, 1)} ms" : "–";
private string Normal(double? value) => ShowNormal && value is { } v ? $" ({Display.Number(v, 1)})" : "";
private static string Files(SQLInsight.Core.Data.DiskActivity d) =>
d.DataFiles + d.LogFiles == 0 ? "–" : $"{d.DataFiles} data · {d.LogFiles} log";
private static bool Worse(double? now, double? normal) => now is { } n && normal is > 0 and var m && n >= m * 2 && n - m >= 2;
}