为什么我的数据库应用程序那么慢?
Dan Turner 24 August 2017
当你的应用程序运行的非常慢的时候,你的下意识的反应是去责备数据库查询设置。那是不容置疑的如果一些较为严重的延迟可以归咎于缺少索引或一些不必要的锁定,但是,就像在戏剧舞台上一样,也会有一些潜在的反派角色存在,包括你的网络和你的应用程序本身。Dan Turner指出你可以通过解析细节来确定问题出在什么地方以便节省更多的时间和金钱。
运行缓慢会首先影响终端的用户,很快也会影响整个团队,包括DBA,研发团队,以及网络管理员和系统管理员维护硬件。
许多人会参与到这里,他们中的每一个人都会有自己的观点在这个问题上,同时也很难确定解决这个问题的真正的瓶颈在哪里。
广泛的说,有两个主要的原因影响这SQL的运行速度问题:
1、网络问题:关于“管道”的速度和容量SQL应用程序客户机连接到数据库
2、缓慢的处理时间:在结束的管道中有关处理请求的速度和效率
在这篇文章中,我们将探索更多的、有关于如何诊断这些问题的细节。
网络问题:
网络性能问题大致可以分解为相关问题的响应速度和网络的容量,即一组可以传输多少数据在特定的时间内。
当然,这两个是相互联系的。 如果你的应用程序所产生的网络流量(或其他应用程序在同一网络)是压倒性的可用带宽,这反过来会增加延迟。
延迟
延迟的时间发送一个TCP数据包之间的应用程序和SQL服务器。 你会延迟到DB和。 人们通常谈论的往返延迟时间:即往返的时间
图1显示了一个60毫秒往返
带宽
人们经常谈论“大小管”当讨论带宽和这是一个很好的类比(+听起来淘气):胖你管,你马上可以通过更多的数据。
如果你的应用需要接收10 Mb响应中的可能真正引起问题(80 Mb)和20 Mb / s的连接,响应将需要至少4秒才能被接受。 如果你有一个10 mb / s的连接将至少需要8秒才能被接受。 如果其他人在您的网络流媒体权力的游戏,这将减少可用带宽供您使用。
应用程序问题:缓慢的处理时间
每当客户端发送一个请求到SQL服务器,来检索所需的数据集,满足一个请求所需的总处理时间由两部分组成:
1、应用程序处理时间:需要多长时间从以前的响应应用程序来处理数据,在发送下一个请求
2、SQL处理时间:SQL话多久的时间处理之前发送响应的请求
图2提供了一个简单的说明这个概念
时间都去哪儿了?
我们花了很多时间研究客户机/服务器SQL应用程序的性能,并且有压倒性数量的不同的工具,脚本和方法来帮助你解决任何数量的不同类型的性能问题。
那么,当面对缓慢的应用程序响应时间,我们迅速查明问题的根源? 图3中的流程图显示了一个系统化的方法来处理这个问题。
在调查性能问题,你可能有一个以上的问题。 值得关注的几个应用程序的不同部分。这是一个普遍的问题吗? 还是有些地方比别人慢得多?
最好是从小事做起。 它会使生活更容易如果你能专注于特定领域的应用,特别慢,例如假设当你点击“选择所有”按钮在发票页面,需要10秒加载的结果。 专注于一个小的可重复的流程会让你隔离问题。
当然,下一个问题回答是为什么它在10秒?第一次和缩小问题的简单的方法是运行应用程序尽可能接近SQL Server,在同一台机器上,或者在同一局域网。
如果在有效地去除任何网络延迟和带宽约束突然需要第二个或更少的选择所有的发票,然后你需要调查什么网络问题可能是吃了剩下的所有的时间。
如果应用程序仍需要大约10秒加载的结果,那么恭喜你,你再次取消2 4的问题! 现在,您需要看看这个处理的大部分时间花费。
让我们仔细看看如何工作的大部分时间都用在哪里。 你需要Wireshark或SQL分析器(无论你更舒服)。
调查应用程序处理时间
你会看到在两个地方之一:将响应发送到应用程序之间和下一个请求(应用程序处理时间)或发出请求到SQL Server和得到一个响应(SQL处理时间)。
找出哪一个是造成你的问题您可以使用Wireshark或SQL分析器既可以告诉我们近似应用程序和SQL处理时间(尽管确切的数字可能略有不同)。
使用Wireshark
我们可以使用Wireshark捕获网络流量在工作流执行。 使用Wireshark允许我们过滤掉非应用流量,看看时间工作流中的所有数据包之间的区别。
计算近似应用程序处理时间:
1、捕获数据包的工作流:开始Wireshark捕捉并运行应用程序工作流,记住停止捕获流程完成后。 记得选择相关的网络接口和注意,你需要不同的机器上运行应用程序从数据库Wireshark看到交通。 确保你没有运行任何其他本地SQL应用程序其他比你想要捕捉的。
2、摆脱这款交通通过应用过滤器tds然后文件|指定的出口包,给一个文件名,并且保证”显示“被选中。 在Wireshark打开这个新的文件。
3、显示当前和以前的包之间的时差,只需通过添加时间δ列,如下:a.选择编辑|首选项|外观|列;b单击+按钮,改变类型下拉”三角洲的时间”和标题“δ”
4、过滤流量只是请求
(tds.type == 0x01 || tds.type==0x03 || tds.type == 0x0E) && tds.packet_number == 1
上面的过滤器将显示第一个TDS在每个请求包,和δ现在列将显示的最后回应数据包之间的时间之前的请求和下一个请求。 确保数据包下令“不。”列,这将确保数据包的顺序发送/接收。
1、导出为CSV通过导航文件|出口包解剖|为CSV
2、计算应用程序处理时间以秒为单位——在Excel中打开CSV和总结中的值δ列。
得到近似SQL处理时间:
1、恢复您在步骤2中创建的文件。 Wireshark上面,过滤流量响应:
2、导出为CSV通过导航文件|出口包解剖|为CSV
3、SQL处理时间以秒为单位计算——在Excel中打开CSV和总结中的值δ列。
使用SQL分析器
尽管收集诊断数据使用SQL分析器是您的工作流添加了一些开销,它仍然应该给你一个广泛的处理时间。 您可以最小化这个开销通过运行一个服务器端跟踪,然后导出数据如下所述。 另外,如果你有信心扩展事件和XQuery,你应该能够得到类似的数据通过这条路线。
首先获取一个分析器工作流程的跟踪,只是用“标准(默认)”跟踪模板。 确保没有其他的数据库在同一时间所以你只捕获你的交通。 一旦你捕获跟踪的工作负载,将它保存到一个跟踪表使用文件|另存为|跟踪表。
在SQL管理工作室,与以下两个查询查询您创建的表给你近似应用程序和SQL处理时间:
/* Calculate approximate SQL Processing time for RPCs and SQL Batch queries*/
SELECT SUM(DATEDIFF(MILLISECOND, StartTime, EndTime)) AS 'SQL Processing Time in ms'
FROM TraceTable
WHERE EventClass IN ( 10, 12 );
-- Selects the sum of the time difference between the start and end times
-- for event classes 10 (RPC:Completed) and 12 (SQL:BatchCompleted)
/* Calculate approximate app processing time*/
WITH Events
AS (SELECT *
FROM TraceTable
WHERE EventClass IN ( 10, 11, 12, 13 )
)
SELECT SUM(DATEDIFF(MILLISECOND, PreviousRow.EndTime, CurrentRow.StartTime)) AS 'App Processing Time in ms'
FROM Events CurrentRow
JOIN Events PreviousRow
ON CurrentRow.RowNumber = PreviousRow.RowNumber + 1
WHERE CurrentRow.eventclass IN ( 11, 13 )
AND PreviousRow.eventclass IN ( 10, 12 );
-- Select the sum of the time difference between an end of query event
-- (either 10 RPC:Completed or 12 SQL:BatchCompleted)
-- and the next query starting event
-- (either 11 RPC:Starting or 13 SQL:BatchStarting)
调查延迟和带宽的问题
如果应用程序快速本地运行的时候,它看起来像你有网络问题。 此时,您需要知道应用程序和SQL服务器之间的延迟。 你可以得到一个粗略的从平,它会告诉你时间两者之间往返。 试着把测量时,网络是在低负载高网络负载可以增加ping时间。
如果你数一数查询应用程序的问题,你可以工作多少时间被延迟。
Wireshark的查询,您可以应用下面的过滤器,然后看看状态栏的“显示”数:
(tds.type == 0x01 || tds.type==0x03 || tds.type == 0x0E) && tds.packet_number == 1
你需要用这个查询统计的网络延迟(ping值)。 例如,如果应用程序发送100查询和网络延迟是60 ms总运输时间是100 * 60 = 6000毫秒(6秒),而在一个局域网需要100 * 1 = 100毫秒(0.1秒)。
这应该告诉你如果延迟是你的问题。 如果它不是,那么你就一个带宽的问题。
什么时刻。 我们还没有明确见过一个带宽问题,我们排除了其他问题。 我们如何确认? 好问题。 恐怕这有点技巧。
如果你有一个网络级和交通监控设备,和一个专门的连接到SQL server,您可以看看您的工作流是可用带宽饱和。
另外,您需要看多少带宽应用程序使用当你知道你没有带宽瓶颈。 要做到这一点,您需要再次运行应用程序数据库,在Wireshark捕获数据包,检查应用程序所使用的带宽。 再一次,确保你没有运行任何其他本地SQL应用程序其他比你想要捕捉的。
一旦您完成了Wireshark的截图:
1、使用过滤器:tds
2、点击统计数据|对话和蜱虫盒”限制显示过滤器”。 然后你应该看到你的应用工作流的谈话在对话窗口。
3、显示为“使用的带宽字节- > B”和“字节B - >”
重复捕获应用程序运行的时候高延迟网络,再看带宽使用。 如果两者之间存在着巨大的差异,那么你可能是带宽限制。
当然,对于一个精确的比较,你需要类似的硬件上运行SQL服务器和应用程序,在这两个测试。 例如,如果SQL Server上运行的硬件,这将产生更少交通网络在给定的时间。
根本原因分析
很有可能有多个问题! 然而,经历上面概述的步骤之后,您应该能够解释所有时间花在处理工作流。 如果10秒处理时间证明包括SQL处理时间的6秒,3秒的渡越时间,和1第二个应用程序的处理时间,那么你知道如何优化你的调查。
如果主要问题是减缓SQL处理时间,还有很多信息关于优化和跟踪问题。 例如,因为我们已经捕获一个分析器跟踪,盖尔·肖文章给的一个很好的概述如何找到内部的程序和批次跟踪导致性能问题。 同时,乔纳森Kehayias的书对于故障排除常见性能问题深入探讨了在SQL服务器。
相反,如果大部分时间都用在客户端处理,您可能想要考虑配置您的应用程序代码来定位问题。 有很多分析工具根据您的编程语言(例如,对于。 网络语言可以使用蚂蚁从Redgate或dotTrace JetBrains)。
如果你患有网络带宽问题,那么你可能需要限制你请求的数据的大小。 例如,不要使用“SELECT *“当你请求数据。 只返回必要的列,和使用WHERE或HAVING过滤器只返回所需的行。
性能问题的常见原因,根据我们的经验,“健谈”应用程序运行在高延迟网络。 一个健谈的应用程序发送许多重复和不必要的查询,使更多不必要的网络往返。
通常,这些应用程序最初开发,部署,高速局域网,所以“爽直”从未真正引起了一个问题。 会发生什么,当数据移动到另一个位置,如到云? 或一个客户在一个不同的大陆试图访问吗? 或者你需要构建地理上不同的灾难恢复环境吗? 如果你认为每个查询1杨澜女士将60 x 60 ms WAN慢,你可以看到如何杀死你的表现。
简而言之,当编写一个客户端/服务器应用程序,您需要避免频繁执行相同的查询,以减少必要的往返的数量收集所需的数据。 这两种最常见的方法有:
1、重写代码——例如,您可以聚合和过滤服务器上的多个数据集避免查询每个数据集,虽然它并不总是改变应用程序
2、使用查询预取和缓存——有广域网优化工具将做到这一点,但他们有时昂贵,而且很难配置高性能,不引入bug到应用程序中
我们已经做了很多研究这些问题,而发展数据加速器工具,采用了一种利用机器学习的方法预测您的应用程序要做什么,和预取所需的数据,所以当应用程序请求及时准备好了。
总之
确保你工作之前,你的问题是你花了很多时间和金钱在一个可能的解决方案。 我们看到公司花大量的金钱和时间来优化SQL查询,当他们的最大问题是应用程序的性能问题。 相反,我们看到公司将越来越多的内存或cpu到SQL server当这永远无法弥补了网络延迟增加额外的时间。 如果你能确定工作流处理时间是花,你以正确的方式直接您的时间和努力。
希望给你一些想法如何调查自己的应用程序的性能,或开始追踪任何问题。