翻译(五)——Why is My Database Application so Slow?
Why is My Database Application so Slow?
原文链接:https://www.red-gate.com/simple-talk/dotnet/net-performance/database-application-slow/
当你的程序运行很慢事,第一反应应该是归咎于数据库查询。然,某些更为奢侈的延迟可能会被归咎于缺少索引或不必要的锁定,但在这场闹剧中还有其他潜在的反派角色,包括网络和应用程序本身。Dan Turner指出,在深入了解细节之前,你可以通过确定问题的存在来节省大量的时间和金钱。
应用程序缓慢首先影响的是最终用户,但是很快整个团队都会被影响,包括DBA、开发团队、网络管理员和看管硬件的系统管理员。
受影响的人这么多,每个人对可能额的原因都有自己的看法,很难确定瓶颈究竟在哪里。
概括地说, SQL Server应用程序存在性能问题是有两个原因:
1、 网络问题——与连接SQL应用程序客户机到数据库的“管道”的速度和容量有关
2、 处理速度慢——与管道端部处理的速度和效率有关。
在本文中,我们将更详细地讨论如何诊断这些问题,并深入了解性能问题。
网络问题
网络性能问题广泛地分解成与网络响应速度(延迟)或网络容量(带宽)有关的问题,即在一个固定时间内可以传输多少数据。
当然,两者是相互关联的。如果应用程序(或同一网络上的其他应用程序)生成的网络流量压倒了可用带宽,这反过来又可能增加延迟。
延迟
延迟是在应用程序和SQL服务器之间发送TCP数据包所需的时间。你在到达DB的途中和返回途中会产生延迟。人们通常谈论往返时间的延迟:即到达和返回的时间。
图1显示了60毫秒往返。
带宽
数据可以发送或接收的时间量,在kb/s或Mb / s(兆比特每秒)通常用。
人们在讨论带宽时经常谈论“管道的大小”,这是一个很好的类比(加上它听起来很顽皮):你的管道越宽,你一次能通过的数据越多。
如果你的应用程序需要接收一个10字节的响应(80个!)你有一个20兆字节/ s的连接,响应将至少需要4秒才能收到。如果你有一个10Mb/s连接至少需要8秒可收。如果您的网络上的其他人都流权力的游戏,这样会减少你使用的可用带宽。
应用程序问题:缓慢的处理时间
每当客户机向SQL服务器发送请求以检索所需的数据集时,完成请求所需的总处理时间包括:
1、 应用程序处理时间:在发送下一个请求之前,应用程序要处理来自上一个响应的数据需要多长时间
2、 SQL处理时间:SQL在发送响应之前花费多长时间处理请求
图2提供了这一概念的简单说明。
时间花在哪里?
我们花了大量的时间来研究客户机/服务器SQL应用程序的性能,并且有大量不同的工具、脚本和方法帮助你解决各种不同类型的性能问题。
那么,当面对缓慢的应用程序响应时间时,我们如何快速查明问题的根本原因?
图3中的流程图显示了系统地解决问题的方法。
在调查性能问题时,你可能遇到的问题不止一个。多看几个不同部分的程序是很必要的。这是一个普遍的问题吗?或者有些零件比其他零件慢得多?
最好从小处开始。如果你能专注于应用程序的一个特别的领域尤其是特别慢的程序,它会让生活变得更容易,例如当你点击发票页上的“选择所有”按钮时,加载结果需要10秒。专注于一个小的可重复的工作流会让你隔离这个问题。
下一个要回答的问题,当然是为什么要花10秒?缩小问题的第一个也是最简单的方法是在同一台机器上或同一局域网上尽可能接近SQL Server运行应用程序。
如果有效地消除了任何网络延迟和带宽限制,突然需要一秒钟或更少的时间来选择所有的发票,那么您需要调查什么网络问题可能会吞噬所有剩余的时间。
如果应用程序仍然需要大约10秒来加载结果,那么恭喜你,你再次排除了4个问题中的2个!现在,您需要查看这个处理时间的大部分时间是在哪里度过的。
让我们仔细看看如何计算大部分时间都花在了哪里。你会需要Wireshark或SQL事件探查器(选取二者中任一个你用着好的)
调查应用程序处理时间
您将看到两个地方中的一个时间:发送对应用程序的响应和获取下一个请求(应用程序处理时间),或者发出请求到SQL服务器并获得响应(SQL处理时间)。
为了找出是哪一个造成你的问题,你可以使用Wireshark或者SQL事件探查器。这两个都可以告诉我们大致的app和SQL的处理时间(虽然确切的数字可能略有不同)
使用Wireshark
我们可以使用Wireshark捕获网络流量而工作流执行。使用wireshark可以让我们过滤掉非应用流量看工作流中的所有数据包之间的时间差。
计算近似应用程序处理时间:
1、捕获数据包的流程:启动Wireshark捕获和运行应用程序的工作流程,记得曾经的工作流是完全停止捕获。记得要选择相应的网络接口,请注意,你将需要运行的应用程序对数据库不同的机器为Wireshark看到交通。确保您没有运行任何其他本地SQL应用程序,而不是试图捕获的其他SQL应用程序。
2、通过应用过滤器TDS然后文件|出口指定包摆脱非APP的流量得到的,给一个文件名,确保“显示”选择。在Wireshark打开这个新文件。
3、通过添加时间增量列显示当前和以前数据包之间的时间差,如下所示:
A:选择编辑/参数选择/外/|列
B:单击+按钮,将类型下拉框改为“delta时间”,标题改为“delta”
4、将流量过滤为只请求:
(tds.type = = 0x01 | | TDS。型= = 0x03 | | tds.type = = 0x0e)和tds.packet_number = = 1
上面的过滤器将只显示每个请求中的第一个TDS包,而delta列现在显示上次请求的最后一个响应包和下一个请求之间的时间。确保数据包是由“否”列排列的,因为这将确保数据包按发送/接收的顺序排列。
5、输出为CSV文件,在导航文件|口包夹层| CSV
6、以秒计算应用程序处理时间-在Excel中打开CSV并在delta列中总结值。
获得近似SQL处理时间:
1、重新打开步骤2中创建的文件。以上wireshark过滤流量只是反应:
tds.type = = 0x04 & tds.packet_number = = 1
上面的过滤器将只显示每个响应中的第一个TDS包,而delta列现在显示上次请求的最后一个请求包和从SQL服务器发回的第一个响应包之间的时间。同样,确保包由“否”列排序。
2、输出为CSV文件,在导航文件|口包夹层| CSV
3、以秒计算SQL处理时间——在Excel中打开CSV并在delta列中总结值。
使用SQL事件探查器
尽管使用SQL分析器收集诊断数据会给工作流程增加一些开销,但它仍然可以给您一个大致的处理时间的图片。您可以通过运行服务器端跟踪来最小化开销,然后按照下面描述的方式导出数据。或者,如果您对扩展事件和XQuery有信心,那么您应该能够通过该路由获得类似的数据。
首先捕获工作流的探查器跟踪,只使用“标准(默认)”跟踪模板。确保没有其他东西同时击中数据库,所以你只捕获你的流量。一旦你在跟踪中捕获的工作量,把它保存到一个文件|使用跟踪表保存为|跟踪表。
在SQL Management Studio中,用以下两个查询查询您创建的表,以便给您大致的应用程序和SQL处理时间:
调查延迟和带宽问题
如果在本地运行时应用程序很快,那么看起来您有网络问题。在这一点上,您需要知道应用程序和SQL Server之间的延迟。你可以从ping得到一个粗略的概念,它会告诉你两个来回的时间。当网络处于低负载时,尝试测量,因为高网络负载可以增加ping时间。
如果计算应用程序发出的查询数,您可以计算出延迟所占用的时间。
要查询从Wireshark的数量,你可以使用下面的过滤然后看看”显示状态栏中的”数:
要获得SQL探查器中的查询数,请按照前面描述的方式创建跟踪表,并运行以下查询:
您需要将此查询计数乘以网络延迟(ping值)。例如,如果应用程序发送100个查询和你的网络延迟为60ms,然后总时差是100 * 60 = 6000ms(6秒),而在一个局域网需要100 * 1 = 100ms(0.1秒)。
这应该告诉你是否延迟是你的问题。如果不是,那么你就有带宽问题了。
不过这一刻。我们没有明确地看到带宽问题,我们排除了其他问题。我们怎样确认呢?伟大的问题。这一点技巧恐怕。
如果您有一个具有流量监控的网络级设备,以及一个与SQL Server的专用连接,您可以查看并查看您的工作流程是否占用了可用带宽。
或者,当您知道没有带宽瓶颈时,您需要查看应用程序使用的带宽有多大。要做到这一点,你需要再次运行应用程序与数据库,捕捉Wireshark的数据包,并检查应用程序所使用的带宽。同样,确保您没有运行任何其他本地SQL应用程序,而不是试图捕获的其他SQL应用程序。
一旦你已经完成在Wireshark捕获:
1、使用过滤器:TDS
2、点击统计|谈话和勾选框“限制显示过滤器”。然后,您将在对话窗口中看到应用程序工作流程会话
3、所使用的带宽显示为“字节A”和“字节B”。
在高延迟网络上运行应用程序时重复捕获,并再次查看所使用的带宽。如果两者之间有很大的差异,那么你可能是带宽受限的。
当然,为了进行精确的比较,您需要在相同的硬件上运行SQL Server和应用程序,在这两个测试中。例如,如果SQL Server运行在功能不太强大的硬件上,那么在给定的时间内,它将在整个网络上产生更少的通信量。
根本原因分析
很有可能你有多个问题!然而,在完成上面的步骤之后,您应该能够解释处理工作流所花费的所有时间。如果10秒的处理时间包含6秒的SQL处理时间、3秒的传输时间和1秒的应用程序处理时间,那么您就知道如何对调查进行优先级排序。
如果主要问题是缓慢的SQL处理时间,那么就有很多关于调优和跟踪问题的信息。例如,由于我们已经捕获了一个探查器跟踪,Gail Shaw的文章很好地概述了如何在跟踪中找到对性能问题贡献最大的跟踪过程和批次。另外,Jonathan Kehayias的书是一个伟大的更深的下潜到常见的故障诊断性能问题的SQL服务器。
相反,如果大部分时间都花在客户端处理中,您可能需要考虑分析应用程序代码来定位问题。有分析工具有很多取决于你的编程语言(例如,对于.NET语言,您可以使用蚂蚁从JetBrains展鹏或dottrace)。
如果您正在遭受网络带宽问题,那么您可能需要限制您请求的数据的大小。例如,在请求数据时不要使用“选择*”。只返回必需的列,并在其中使用或拥有筛选器以返回必需的行。
性能问题的一个很常见的原因,在我们的经验中,运行在高延迟网络聊天”的应用。一个聊天应用程序是一个将许多重复和不必要的查询方式,使更多不必要的网络往返。
通常,这些应用程序最初开发,部署,高速局域网,所以“爽直”从未真正引起了一个问题。但是,当数据移动到不同的位置,比如云时,会发生什么呢?或者在不同大陆的客户尝试访问它?或者您需要构建地理上不同的灾难恢复环境?如果你考虑每一个查询在1ms的局域网将60x慢一个60MS湾,你可以看到这是如何杀死你的表现。
简而言之,在编写客户机/服务器应用程序时,需要避免频繁执行相同的查询,以尽量减少必要的往返次数,以收集所需的数据。这两种最常见的方法是:
1、重写代码——例如,您可以聚合和过滤服务器上的多个数据集,以避免对每个数据集进行查询,尽管并不总是要更改应用程序。
2、使用查询预取和缓存——有一些WAN优化工具可以做到这一点,但它们有时很昂贵,而且很难配置以获得高性能,而不向应用程序引入bug。
在开发数据加速器工具时,我们已经对这些问题做了大量的研究,并且采用了一种方法,它使用机器学习来预测您的应用程序将要做什么,并预取所需的数据,以便在应用程序请求它时及时准备好。
总结
在你花大量的时间和金钱在一个可能的解决方案之前,一定要弄清楚你的问题在哪里。我们已经看到公司花费大量的金钱和工时来优化SQL查询,当它们的最大问题是应用程序性能问题时。相反,我们已经看到公司将越来越多的RAM或CPU放入SQL服务器,因为这永远不能弥补额外的网络延迟时间。如果您能够准确地确定工作流处理时间的真正位置,您就可以用正确的方法指导您的时间和工作。
希望这给了你一些关于如何调查你自己的应用程序性能的想法,或者开始追踪你可能遇到的任何问题。