当您的应用程序运行缓慢时,反射操做是指责数据库查询。
毫无疑问,一些更为奢侈的拖延可能会由于缺失的指数或没必要要的锁定而被指责,但还有其余潜在恶做剧,包括网络和应用自己。 Dan
Turner指出,你能够节省大量的时间和金钱,经过努力肯定问题所在的位置,而后潜入细节。数据库
低应用程序首先影响终端用户,可是整个团队很快就会感觉到影响,包括DBA,Dev团队,网络管理员以及照管硬件的系统管理员。编程
有这么多人参与,每一个人都有本身的见解,可能的缘由,可能很难肯定瓶颈在哪里。缓存
通常来讲,SQL Server应用程序的性能问题有两个主要缘由:服务器
在本文中,咱们将详细介绍如何诊断这些问题,并了解最底层的性能问题。网络
网络性能问题普遍地分解为与网络响应速度(延迟)或网络容量(带宽)相关的问题,即在必定时间内可传输多少数据。app
固然这二者是相互联系的。 若是您的应用程序(或同一网络上的其余应用程序)生成的网络流量压倒可用带宽,则这可能会增长延迟。机器学习
延迟是在应用程序和SQL Server之间发送TCP数据包所需的时间。 在DB上和降低的路上,您会产生延迟。 人们一般会谈论往返时间的延迟:即到达那里的时间编程语言
图1显示了60毫秒的往返行程。图1工具
能够以必定的时间量发送或接收的数据量,一般以kb / s或Mb / s(兆比特每秒)为单位。性能
在讨论带宽时,人们常常谈论“管道的大小”,这是一个很好的类比(再加上它听起来很顽皮):你的管道越多,你能够一次得到更多的数据。
若是您的应用程序须要接收10兆字节的响应(这是80兆比特!),而且您有20 Mb / s的链接,则响应将至少须要4秒钟。 若是您有10Mb / s链接,则至少须要8秒钟的时间。 若是您的网络上的其余人正在流式传播“权力”游戏,那么这将下降可用带宽以供您使用。
每当客户端向SQL Server发送请求时,要检索所需的数据集,完成请求所需的总处理时间都包括:
应用程序处理时间:应用程序在发送下一个请求以前处理上一个响应中的数据须要多长时间
SQL处理时间:SQL在发送响应以前花费多少时间处理请求
图2提供了这个概念的简单说明。图2
咱们花费了大量时间来调查客户端/服务器SQL应用程序的性能,而且还有绝大多数不一样的工具,脚本和方法来帮助您排除任何数量的不一样类型的性能问题。
那么当面对缓慢的应用程序响应时间的时候,咱们可否快速找出问题的根本缘由? 图3中的流程图显示了一种系统的方法来解决问题。
图3
调查性能问题时,可能有多个问题。值得一看的应用程序的几个不一样的部分。这是一个广泛的问题吗?仍是比别人慢一些?
最好小开始。若是您能够专一于特别缓慢的应用程序的某个特定区域,那么可让生活更轻松,例如,当您点击发票页面上的“全选”按钮时,加载结果须要10秒钟。专一于一个小型可重复的工做流将让您隔离问题。
接下来的问题固然是为何要花10秒钟?缩小问题的第一个也是最简单的方法是将应用程序尽量靠近SQL Server,在同一台机器上或在同一个LAN上运行。
若是有效地消除了任何网络延迟和带宽限制,则忽然须要一秒钟或更短期才能选择全部发票,那么您须要调查哪些网络问题可能在其他时间内消失。
若是应用程序仍然须要10秒钟的时间来加载结果,那么恭喜,您再次消除了4个问题中的2个!如今,您须要查看处理时间大部分在哪里。
咱们来仔细看一下如何解决这段时间大部分消费的地方。您将须要Wireshark或SQL Profiler(不管您更加温馨)。
您将在两个地方之间看到时间:发送应用程序的响应和获取下一个请求(应用程序处理时间)之间或在发出SQL Server请求和获取响应(SQL处理时间)之间的时间。
要解决哪个致使您的问题,您可使用Wireshark或SQL Profiler,由于二者均可以告诉咱们大体的应用程序和SQL处理时间(尽管确切的数字可能会略有不一样)。
咱们可使用Wireshark在工做流执行时捕获网络流量。使用Wireshark,咱们能够过滤非应用程序流量,并查看工做流中全部数据包之间的时差。
计算近似应用处理时间:
上述过滤器将仅显示每一个请求中的第一个TDS数据包,“增量”列如今将显示先前请求的最后一个响应数据包与下次请求之间的时间。确保数据包由“否”列排序,由于这将确保数据包按照发送/接收的顺序。
要获取大体的SQL处理时间:
上述过滤器将仅显示每一个响应中的第一个TDS数据包,“增量”列如今将显示先前请求的最后一个请求数据包与从SQL Server发回的第一个响应数据包之间的时间。一样,请确保数据包由“否”列排序。
虽然已知使用SQL Profiler收集诊断数据会为您的工做流程增长一些开销,但它仍然能够给您一个普遍的处理时间。 您能够经过运行服务器端跟踪,而后以下所述导出数据来最小化此开销。 或者,若是您对扩展事件和XQuery有信心,您应该能够经过该路径获取相似的数据。
首先经过捕获工做流的Profiler跟踪,只需使用“标准(默认)”跟踪模板。 确保没有其余的东西在同一时间触发数据库,因此你只捕获你的流量。 捕获跟踪中的工做负载后,使用File |将其保存到跟踪表 另存为| 跟踪表。
在SQL Management Studio中,使用如下两个查询查询您建立的表,以便为您提供大体的应用程序和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 Server之间的延迟。 你能够从一个ping上获得一个粗略的想法,这将告诉你二者之间的往返时间。 当网络处于低负载状态时,尝试并进行测量,由于网络负载高可能会增长ping次数。
若是您计算应用程序发出的查询数量,您能够计算延迟所花费的时间。
要获取Wireshark的查询数量,您能够应用如下过滤器,而后查看状态栏中的“显示”计数:
(tds.type == 0x01 || tds.type==0x03 || tds.type == 0x0E) && tds.packet_number == 1
要获取SQL Profiler中的查询数量,请按前述建立一个跟踪表,并运行如下查询:
SELECT COUNT(1) FROM TraceTable WHERE EventClass in (11,13)
您须要将此查询计数乘以网络延迟(ping值)。例如,若是应用程序发送100个查询,而且您的网络延迟为60ms,则总通行时间为100 60 = 6000ms(6秒),而在LAN上,则须要100 1 = 100ms(0.1秒)。
这应该告诉你延迟是不是你的问题。若是不是,那么你有一个带宽问题。
过了一下子咱们没有明确看到带宽问题,咱们只是排除了其余问题。咱们如何确认?很好的问题恐怕会有点儿吃惊
若是您有一个具备流量监控的网络级设备,以及与SQL Server的专用链接,则能够查看您的工做流程是否使可用带宽饱和。
或者,当您知道您没有带宽瓶颈时,您须要查看应用程序使用多少带宽。为此,您还须要运行靠近数据库的应用程序,捕获Wireshark中的数据包,并检查应用程序使用的带宽。一样,请确保您没有运行任何其余本地SQL应用程序,而不是您尝试捕获的其余本地SQL应用程序。
一旦你完成了Wireshark的捕获:
固然,为了准确比较,您须要在两个测试中运行SQL Server和相似硬件上的应用程序。例如,若是SQL Server在功能不强的硬件上运行,那么在给定的时间内,它将在整个网络中产生更少的流量。
颇有可能你有多个问题!可是,在完成上述步骤以后,您应该可以将全部时间用于处理工做流程。若是10秒的处理时间显示为6秒的SQL处理时间,3秒的传输时间和1秒的应用处理时间,那么您将了解如何肯定您的调查的优先级。
若是主要问题是缓慢的SQL处理时间,那么有不少关于调优和跟踪问题的信息。例如,因为咱们已经捕获了Profiler跟踪,Gail Shaw的文章很好地概述了如何在跟踪中查找对性能问题最有贡献的过程和批处理。此外,Jonathan Kehayias的书很是适合对SQL Server中常见的性能问题进行故障排除。
相反,若是大部分时间花在客户端处理中,您可能须要考虑对应用程序代码进行分析以查找问题。根据您的编程语言(例如,对于.NET语言,您可使用来自Redgate的ANTS或JetBrains的dotTrace),有不少分析工具。
若是您遇到网络带宽问题,则可能须要限制您要求的数据的大小。例如,在请求数据时不要使用“SELECT *”。只返回必要的列,并使用WHERE或HAVING过滤器仅返回必要的行。
在咱们的经验中,性能问题的一个常见缘由是经过高延迟网络运行“聊天”应用程序。一个聊天应用程序是发送许多重复和没必要要的查询,使得更多的网络往返行程比必要。
一般,这些应用程序最初是在高速LAN上开发并部署的,因此“chattiness”历来没有真正引发问题。当数据移动到不一样的位置(如云端)时,会发生什么?或者不一样大陆的客户试图访问?或者您须要构建地理上多样化的灾难恢复环境?若是您考虑在一个1ms的LAN上的每一个查询在60ms广域网上的速度将会下降60倍,那么您能够看到这样会如何影响您的性能。
简而言之,在编写客户端/服务器应用程序时,您须要避免频繁执行相同的查询,以最大限度地减小必要的往返次数来收集所需的数据。这两种最多见的方法是:
咱们对这些问题进行了大量的研究,同时开发了数据加速器工具,并采用了一种使用机器学习来预测应用程序要作什么的方法,并预取所需的数据,所以它准备就绪由于应用程序请求它。
在您花费大量时间和金钱的可能解决方案以前,确保您解决问题所在。 咱们已经看到,当公司最大的问题出如今应用程序性能问题上时,公司花费大量资金和人力时间来优化SQL查询。 相反,咱们已经看到,企业将愈来愈多的内存或CPU放入SQL服务器,这样作永远不会弥补网络延迟的额外时间。 若是您能够肯定工做流程处理时间的真正用途,您能够以正确的方式指导您的时间和精力。
但愿这可让您了解如何调查本身的应用程序的性能,或者开始追踪您可能遇到的任何问题。