基于 Web 的实时 SQL Server 性能仪表板






4.76/5 (62投票s)
SQL Server 性能仪表板(SSPD)是一个小型开源Web应用程序,可近乎实时地显示一个或多个SQL Server实例及其数据库的性能和问题。
引言
SQL Server 性能仪表板(SSPD)是一个小型开源Web应用程序,可近乎实时地显示一个或多个SQL Server实例及其数据库的性能和问题。它使用动态管理视图(DMV)从详细输出中收集有用的数据,并结合实用存储过程,从而从中获取有意义、易于理解的信息。您可以使用它快速发现阻塞查询、谁在阻塞谁、消耗高CPU或磁盘的昂贵查询、查看是否存在异常锁定、非常高的磁盘活动等问题。
查看实时演示
http://dashboard.omaralzabir.com/
获取代码
二进制文件在此处,您可以将其解压到IIS文件夹中,将连接字符串放入web.config文件中,即可开始使用。
SqlServerPerformanceDashboard GitHub项目二进制文件
如果您不使用sa用户,而是使用自己的用户,请为该用户授予正确的权限。
USE master;
GO
GRANT VIEW SERVER STATE TO MyUser;
GO
这是一个连接字符串示例
<add name="DB1" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=YourDatabase;User ID=MyUser;Password=MyPassword" />
或者您可以从GitHub项目站点获取源代码:
https://github.com/oazabir/SQLServerPerformanceDashboard/
为什么不使用SQL Server Management Studio?
SQL Server Management Studio附带活动报告,显示服务器的实时性能,以及各种报告以显示顶级查询、阻塞会话等。这些当然非常有用,但我们需要的是有人确切地告诉我们查询有什么问题,或者某个特定的WAIT有什么问题,或者某些看起来很高的图表到底有什么问题。例如,在“Top IO query report”(顶级IO查询报告)中,了解查询的哪一部分导致高IO会很有用。是否存在表扫描?索引扫描?同样,在阻塞会话报告中,了解谁在阻塞谁会很有用。SSPD试图通过确切地告诉我们问题所在来减轻我们的痛苦。此外,它作为一个网站提供,无需启动SQL Server Management Studio并运行报告即可随时使用。SSPD还会实时刷新,每5-10秒显示服务器的最新状态。
服务器上现在发生了什么?
SSPD使用一些自定义脚本来查询DMV并理解其含义。例如,我们来看第一个:“What's going on”(正在发生什么)。它向您显示当前正在运行的查询的近乎实时视图,并且还会告诉您这些查询的真正问题。
它使用了Adam Machanic制作的著名 Who is Active 脚本,该脚本提供了有关服务器上当前正在发生的事情的非常有益的视图。
一旦它拉取输出,它就会绑定到一个 DataGrid
,并且对于每一行,然后它会检查是否有超出图表范围的内容。
<asp:GridView CssClass="table table-striped" ID="GridView1" runat="server" DataSourceID="sqlDataSource" EnableModelValidation="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<%# Convert.ToDecimal(Eval("CPU")) > 1000 ? "<span class='label label-warning'>High CPU</span>" : "" %>
<%# Convert.ToDecimal(Eval("physical_reads")) > 1000 ? "<span class='label label-warning'>High Physical Read</span>" : "" %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
No Query running at the moment.
</EmptyDataTemplate>
</asp:GridView>
在这里您可以看到,它会查看特定值,如果这些值异常高,它会注入一个警告标签。这使您无需扫描输出以查看是否有异常。您可以轻松设置所需的阈值,并在屏幕上获得即时警告标签。
无论您在哪里看到查询,都可以单击它以查看完整详细信息。
这可能是日常监控中最有用的功能。它查询SQL Server自上次重启或调用DBCC FREEPROCCACHE
以来运行的查询的缓存计划。然后它不仅显示最昂贵的查询,还准确显示查询的哪个部分导致了问题。您可以看到导致最高IO负载的WHERE子句。
在这里你可以看到一些表扫描正在进行。你还可以看到WHERE子句中导致表扫描的部分。
如果单击查询(向右滚动),它将显示完整的查询。
昂贵的存储过程
接下来是“昂贵的存储过程”视图,它显示了在CPU或IO方面最昂贵的存储过程。
您可以看到 QueryOrders
的 AvgLogicalReads
非常高。那个存储过程正在拖垮数据库。
工作原理
看,妈妈,没有AJAX!
您会注意到面板会定期刷新。您可能认为我正在使用AJAX调用一些服务器端Web服务,以获取JSON/XML响应,然后使用一些jQuery模板渲染HTML输出。不,我使用的是我们的祖先世代幸福使用的东西。自然、有机的IFRAME解决方案,没有副作用。每个面板的HTML输出都来自单独的ASP.NET页面,通过IFRAME,然后它们被注入到主仪表板页面上的DIV中。
这种方法有几个好处
- 这些小部件是单独的页面,用户可以在完整的浏览器视图中直接浏览。
- 每个小部件都是一个普通的ASP.NET页面。无需构建Web服务来以JSON/XML格式返回数据。也无需任何通常用于序列化为JSON/XML的实体类。
- HTML内容是在服务器端使用常规ASP.NET生成的。因此无需使用任何基于Javascript的HTML模板库。
- 由于不需要AJAX或HTML模板,因此无需担心jQuery或其插件在新版本中破坏兼容性,也无需定期更新javascript库。
我们来看看如何做到这一点。首先是绘制面板的HTML标记
<div class="row">
<div class="panel panel-success">
<div class="panel-heading"><a href="WhoIsActive.aspx?c=<%= ConnectionString %>">What's going on</a></div>
<div class="panel-body panel-body-height" id="WhoIsActive">
<div class="progress">
<div class="progress-bar progress-bar-striped" style="width: 60%"><span class="sr-only">100% Complete</span></div>
</div>
</div>
<iframe class="content_loader" onload="setContent(this, 'WhoIsActive')" src="WhoIsActive.aspx?c=<%= ConnectionString %>" style="width: 100%; height: 100%; border: none; display: none" frameborder="0"></iframe>
</div>
</div>
这是从 Twitter Bootstrap主题 中提取的标记。
您会注意到那里有一个不可见的IFRAME。当IFRAME加载时,它会调用 setContent
函数。该函数获取IFRAME的全部内容并将其注入到panel-body div中。
function setContent(iframe, id) {
...
$('#' + id)
.html($(iframe).contents().find("form").html())
.dblclick(function () {
iframe.contentWindow.location.reload();
})
...
}
瞧,这是一个干净的类似AJAX的解决方案,无需任何AJAX:没有XMLHTTP,没有JSON管道,没有HTML模板,也没有服务器端Web服务。
现在,这对于挂钩在IFRAME内部的任何事件处理程序都无效。那么,点击查询如何显示带有完整查询的弹出窗口呢?此外,如果它是一个IFRAME,弹出窗口难道不应该实际出现在IFRAME内部吗?
点击功能在主仪表板页面上完成。在将内容注入DIV后,它会挂钩点击处理程序,以在主页面上显示弹出窗口。
function setContent(iframe, id) {
$('#' + id)
.find('td.large-cell').off('click');
if ($('#' + id).scrollLeft() == 0) {
$('#' + id)
.html($(iframe).contents().find("form").html())
.dblclick(function () {
iframe.contentWindow.location.reload();
})
.find('td.large-cell').find('div').click(function () {
$('#content_text').text($(this).html());
$('#basic-modal-content').modal();
});
}
这里它寻找任何具有large-cell类的元素。然后它会挂钩其点击事件并显示模态对话框。模态对话框来自 Eric Martin的SimpleModal 插件。
绘制图表
图表使用jQuery插件 Flot 来将一些性能计数器渲染为运行图表。
有一个PerformanceCounter.aspx,负责渲染显示性能计数器的表格。它选择了一些重要的计数器,并将其标记为显示在图表上。首先它遍历表格,寻找计数器,并将计数器的标签标记为x轴,计数器的值标记为y轴。
var plot = ["Batch Requests/sec", "Full Scans/sec", "SQL Compilations/sec", "Total Latch Wait Time (ms)"];
$('td').each(function (i, e) {
td = $(e);
if (td.text().trim().length > 0) {
for (var i = 0; i < plot.length; i ++) {
if (plot[i] == td.text().trim()) {
if (td.prev().text() == "_Total" || td.prev().text().trim().length == 0) {
td.addClass("x-axis");
td.next().addClass("y-axis");
}
}
}
}
})
现在,这个页面托管在仪表板页面的IFRAME中。因此,仪表板页面会扫描IFRAME内容,查找这些标签,获取它们的值并将其传递给Flot图表插件。
$(iframe).contents().find("form").find(".x-axis").each(function (i, e) {
var x = $(e);
var y = x.next('.y-axis');
var xname = x.text();
var yvalue = parseInt(y.text());
if (datasets[xname]) {
var data = datasets[xname].data;
data.pop();
data.splice(0, 0, yvalue);
}
});
更新Flot图表的其余工作由常规Flot代码完成。
function updatePlot() {
var index = 0;
$.each(datasets, function (key, val) {
var items = [];
for (var i = 0; i < val.data.length; i++)
items.push([i, val.data[i]]);
var data = { color: val.color, data: items };
if (plots[index] != null) {
plot = plots[index];
plot.setData([data]);
plot.draw();
}
else {
plot = $.plot("#placeholder" + (index + 1), [data], {
series: {
//shadowSize: 0 // Drawing is faster without shadows
},
lines: { show: true, fill: true },
grid: {
hoverable: true,
clickable: true
},
yaxis: {
min: 0,
max: val.ymax
},
xaxis: {
show: false
}
});
就这样!再次,没有AJAX,没有Web服务,没有HTML模板,没有JSON管道。纯粹的有机IFRAME和HTML。
结论
SSPD致力于使我们轻松监控SQL Server的健康状况。它从SQL Server内置视图产生的冗长数据中提取有意义的信息。它准确地显示问题所在。您可以随意自定义代码,添加自己的警告、自己的阈值,使其满足您的特定需求。