【翻译】为什么我的数据库应用这么慢?

为什么我的数据库应用这么慢?

作者:Dan Turner

 

   当你数据库应用运行很慢的时候,反射操作将归咎于数据库查询。当然,某些更为奢侈的延迟可能会被归咎于缺少索引或不必要的锁定,但在电视剧中还有其他潜在的反派角色,包括网络和应用程序本身。Dan Turner指出,在深入了解细节之前,你可以通过确定问题的存在来节省大量的时间和金钱。

 

 

缓慢的应用影响到最终用户,但很快就影响到整个团队,包括DBA、开发团队、网络管理员和系统管理员看硬件。

 

有这么多人参与,每个人都对可能的原因有自己的看法,很难确定瓶颈究竟在哪里。

 

概括地说,SQL Server应用程序存在两个性能方面的问题:

 

网络问题——与连接SQL应用程序客户机到数据库的“管道”的速度和容量有关

 

处理速度慢——与管道端部处理的速度和效率有关。

 

在本文中,我们将更详细地讨论如何诊断这些问题,并深入了解性能问题。

 

网络问题

 

网络性能问题广泛地分解成与网络响应速度(延迟)或网络容量(带宽)有关的问题,即在一个固定时间内可以传输多少数据。

 

当然,两者是相互关联的。如果应用程序(或同一网络上的其他应用程序)生成的网络流量压倒了可用带宽,这反过来又可能增加延迟。

 

 

延迟

延迟是在应用程序和SQL服务器之间发送TCP数据包所需的时间。你在到达DB的途中和途中会产生延迟。人们通常谈论往返时间的延迟:即到达和返回的时间。

1显示了60毫秒往返。 

带宽

 

数据可以发送或接收的时间量,通常用kb/sMb / s(兆比特每秒)。

 

人们在讨论带宽时经常谈论“管道的大小”,这是一个很好的类比(加上它听起来很顽皮):你的管道越肥,你能立即通过的数据越多。

 

如果你的应用程序需要接收一个10字节的响应(80个!)你有一个20兆字节/ s的连接,响应将至少需要4秒才能收到。如果你有一个10Mb/s连接至少需要8秒可收。如果您的网络上的其他人流动玩权力的游戏,这样会减少你使用的可用带宽。

 

应用程序问题:处理时间慢

 

每当客户机向SQL服务器发送请求,以检索所需的数据集时,完成请求所需的总处理时间包括:

 

应用程序处理时间:在发送下一个请求之前,应用程序要处理来自上一个响应的数据需要多长时间

 

SQL处理时间:SQL在发送响应之前花费多长时间处理请求

 

2提供了这一概念的简单说明。

时间花在了哪里?

 

我们花了大量的时间来研究客户机/服务器SQL应用程序的性能,并且有大量不同的工具、脚本和方法帮助您解决各种不同类型的性能问题。

 

那么,当面对缓慢的应用程序响应时间时,我们如何快速查明问题的根本原因?图3中的流程图显示了系统地解决问题的方法。

在调查性能问题时,可能有不止一个问题。值得一看的几个不同的部分的应用程序。这是一个普遍的问题吗?或者有些零件比其他零件慢得多?

 

最好从小处开始。如果你能专注于应用程序的一个特别的领域,尤其是慢的话,它会让生活变得更容易,例如当你点击发票页上的“选择所有”按钮时,加载结果需要10秒。专注于一个小的可重复的工作流会让你隔离这个问题。

 

下一个要回答的问题,当然是为什么要花10秒?缩小问题的第一个也是最简单的方法是在同一台机器上或同一局域网上尽可能接近SQL Server运行应用程序。

 

如果有效地消除了任何网络延迟和带宽限制,突然需要一秒钟或更少的时间来选择所有的发票,那么您需要调查什么网络问题可能会吞噬所有剩余的时间。

 

如果应用程序仍然需要大约10秒来加载结果,那么恭喜你,你再次排除了4个问题中的2个!现在,您需要查看这个处理时间的大部分时间是在哪里度过的。

 

让我们仔细看看如何计算大部分时间都花在了哪里。你会需要WiresharkSQL事件探查器(选择更适合你的)。

 

调查应用程序处理时间

 

您将看到两个地方中的一个时间:发送对应用程序的响应和获取下一个请求(应用程序处理时间),或者发出请求到SQL服务器并获得响应(SQL处理时间)。

 

找出哪一个是造成你的问题,你可以使用WiresharkSQL事件探查器都可以告诉我们的近似应用程序和SQL的处理时间(虽然确切的数字可能略有不同)。

 

使用Wireshark

 

我们可以使用Wireshark捕获网络流量而工作流执行。使用wireshark可以让我们过滤掉非应用流量看工作流中的所有数据包之间的时间差。

 

计算近似应用程序处理时间:

 

1、捕获数据包的流程:启动Wireshark捕获和运行应用程序的工作流程,记得曾经的工作流是完全停止捕获。记得选择相关的网络接口,并注意,你需要在不同的机器上运行这个应用程序,从数据库到Wireshark,以查看流量。确保您没有运行任何其他本地SQL应用程序,而不是试图捕获的其他SQL应用程序。

 

2、通过应用过滤器消除非应用程序流量TDS然后File | Export Specified Packets给定文件名并确保“显示”被选中。在Wireshark打开这个新文件。

 

3、通过添加时间增量列显示当前和以前数据包之间的时间差,如下所示:

 

  1. Select Edit | Preferences | Appearance | Columns
  2. Click the + button, change the type dropdown to “Delta Time” and the Title to “Delta

 

4、将流量过滤为只请求:

 

(tds.type == 0x01 || tds.type==0x03 || tds.type == 0x0E) && tds.packet_number == 1

 

上面的过滤器将只显示每个请求中的第一个TDS包,而delta列现在显示上次请求的最后一个响应包和下一个请求之间的时间。确保数据包是由“No”列排列的,因为这将确保数据包按发送/接收的顺序排列。

 

5、输出为CSV文件,通过导航File | Export Packet Dissections | As CSV

 

6、以秒计算应用程序处理时间-Excel中打开CSV并在delta列中总结值。

 

获得近似SQL处理时间:

 

1、重新打开步骤2中创建的文件。以上wireshark过滤流量只是反应:

 

tds.type = = 0x04 & tds.packet_number = = 1

 

上面的过滤器将只显示每个响应中的第一个TDS包,而delta列现在显示上次请求的最后一个请求包和从SQL服务器发回的第一个响应包之间的时间。同样,确保包由“No”列排序。

 

2、输出为CSV文件,通过导航File | Export Packet Dissections | As CSV

 

以秒计算应用程序处理时间-Excel中打开CSV并在delta列中总结值。

 

使用SQL事件探查器

 

尽管使用SQL分析器收集诊断数据会给工作流程增加一些开销,但它仍然可以给您一个大致的处理时间的图片。您可以通过运行服务器端跟踪来最小化开销,然后按照下面描述的方式导出数据。或者,如果您对扩展事件和XQuery有信心,那么您应该能够通过该路由获得类似的数据。

 

首先捕获工作流的探查器跟踪,只使用“标准(默认)”跟踪模板。确保没有其他东西同时击中数据库,所以你只捕获你的流量。一旦你在跟踪中捕获的工作量,使用一个跟踪表保存File | Save As | Trace Table.

 

SQL Management Studio中,用以下两个查询查询您创建的表,以便给您大致的应用程序和SQL处理时间:

调查延迟和带宽问题

如果在本地运行时应用程序很快,那么看起来您有网络问题。在这一点上,您需要知道应用程序和SQL Server之间的延迟。你可以从ping得到一个粗略的概念,它会告诉你两个来回的时间。当网络处于低负载时,尝试测量,因为高网络负载可以增加ping时间。

如果计算应用程序发出的查询数,您可以计算出延迟所占用的时间。

要查询从Wireshark的数量,你可以使用下面的过滤然后看看“显示状态栏中的“数:

 

 

要获得SQL探查器中的查询数,请按照前面描述的方式创建跟踪表,并运行以下查询:

 

您需要通过网络延迟(ping)乘以这个查询计数。例如,如果应用程序发送100个查询,而您的网络延迟是60ms,那么总传输时间是100 * 60 = 6000ms(6),而在LAN上则需要100 *1 = 100ms(0.1)

 

这应该告诉你是否延迟是你的问题。如果不是,那么你就有带宽问题了。

 

不过这一刻,我们还没有明确地看到带宽问题,我们只是排除了其他问题。我们怎样确认呢,好问题。恐怕这有点太费事。

 

如果您有一个具有流量监控的网络级设备,以及一个与SQL Server的专用连接,您可以查看并查看您的工作流程是否占用了可用带宽。

 

或者,当您知道没有带宽瓶颈时,您需要查看应用程序使用的带宽有多大。要做到这一点,你需要再次运行应用程序与数据库,捕捉Wireshark的数据包,并检查应用程序所使用的带宽。同样,确保您没有运行任何其他本地SQL应用程序,而不是试图捕获的其他SQL应用程序。

 

一旦你已经完成在Wireshark捕获:

1、使用过滤器:TDS

2、点击Statistics | Conversations和勾选框“Limit to display filter然后,您将在对话窗口中看到应用程序工作流程会话。

3、所使用的带宽显示为“字节A”和“字节B”。

在高延迟网络上运行应用程序时重复捕获,并再次查看所使用的带宽。如果两者之间有很大的差异,那么你可能会受到带宽限制。 

当然,为了进行精确的比较,您需要在两个测试中运行SQL Server和在类似硬件上的应用程序。例如,如果SQL Server运行在功能不太强大的硬件上,那么在给定的时间内,它将在整个网络上产生更少的通信量。

根本原因分析

很有可能你有多重问题!但是,在完成上述步骤之后,您应该能够考虑到花费在处理工作流上的所有时间。如果10秒的处理时间包含6秒的SQL处理时间、3秒的传输时间和1秒的应用程序处理时间,那么您就知道如何优先考虑您的调查。

如果主要问题是缓慢的SQL处理时间,那么有很多关于调优和跟踪问题的信息。例如,由于我们已经捕获了一个Profiler跟踪,Gail Shaw的文章提供了一个关于如何在跟踪中发现过程和批量的很好的概述,这些过程是导致性能问题的主要原因。此外,Jonathan Kehayias的书对于更深入地研究SQL Server中的常见性能问题是非常有用的。

相反,如果大部分时间都用于客户端处理,那么您可能需要考虑对应用程序代码进行分析,以定位问题。有许多基于您的编程语言的分析工具(例如,for.NET语言,您可以使用来自Redgate的ANTS或来自JetBrains的dotTrace。

如果您正遭受网络带宽问题,那么您可能需要限制请求的数据的大小。例如,当您请求数据时,不要使用“SELECT *”。只返回必要的列,并使用WHERE或 HAVING只返回必要的行。

在我们的经验中,性能问题的一个常见原因是在高延迟网络上运行“chatty”应用程序。一个喋喋不休的应用程序可以发送许多重复的和不必要的查询,使更多的网络往返旅行比必要的多。

通常,这些应用程序最初是开发的,并部署到高速LAN,因此“chattiness”从来没有真正造成问题。当数据移动到不同的位置,比如云端,会发生什么呢?或者是一个不同大陆的客户试图访问它?或者您需要构建地理上多样的灾难恢复环境?如果你考虑到1ms LAN上的每一个查询将会在60ms WAN上慢60x,你就会看到这是如何毁掉你的性能的。

简而言之,在编写客户机/服务器应用程序时,您需要避免频繁地执行相同的查询,以最小化收集所需数据所需的往返次数。最常见的两种方法是:

1、重写代码——例如,您可以在服务器上聚合和过滤多个数据集,以避免在每个数据集中生成查询,尽管并不总是更改应用程序

2、使用查询预取和缓存——有一些WAN优化工具可以做到这一点,但是它们有时很昂贵,而且很难配置来获得高性能,而不需要在应用程序中引入bug

在开发我们的数据加速器工具时,我们已经对这些问题做了大量的研究,并采用了一种方法,使用机器学习来预测您的应用程序将要做什么,并预取所需的数据,以便在应用程序请求它时及时地准备好它。

总之

在你花费大量时间和金钱在一个可能的解决方案之前,确保你的问题已经解决了。当他们最大的问题是应用程序性能问题,我们已经看到公司花费大量的金钱和工时优化SQL查询。相反,我们看到公司将越来越多的RAM或CPUs投入到SQL服务器中,这将永远无法弥补网络延迟所增加的额外时间。如果您能够确定工作流处理时间真正花费在哪里,那么您将以正确的方式指导您的时间和工作。

希望这给了你一些关于如何调查你自己的应用程序性能的想法,或者开始追踪你可能有的问题。

 

本翻译来源:

https://www.red-gate.com/simple-talk/dotnet/net-performance/database-application-slow/

posted @ 2017-10-18 20:17  我是墩儿  阅读(304)  评论(0)    收藏  举报