我公司使用的应用程序存在很大的性能问题。我正在研究数据库本身存在许多问题,但是许多问题纯粹与应用程序有关。
在调查中,我发现有数百万个查询命中SQL Server数据库,查询空表。我们大约有300个空表,其中一些表每分钟最多查询100-200次。这些表与我们的业务领域无关,实际上是原始应用程序的一部分,当我的公司与他们签约为我们提供软件解决方案时,供应商并未删除这些原始应用程序。
除了我们怀疑应用程序错误日志中充斥着与此问题相关的错误以外,供应商还向我们保证,应用程序或数据库服务器不会对性能或稳定性造成影响。错误日志泛滥成灾,以至于我们看不到价值超过2分钟的错误来进行诊断。
这些查询的实际成本显然会在CPU周期等方面很低。但是,谁能说出对SQL Server和应用程序有什么影响呢?我怀疑发送请求,确认请求,处理请求,返回请求以及确认应用程序已收到请求的实际机制本身会对性能产生影响。
我们将SQL Server 2008 R2,Oracle Weblogic 11g用于该应用程序。
@ Frisbee-长话短说,我创建了一个包含querytext的表,该表命中了应用程序数据库中的空表,然后对其查询以获取我知道为空的所有表名,并得到了很长的列表。考虑到该应用通常在上午8点至下午6点使用,因此在30天的正常运行时间中,执行次数最高的是270万次执行,因此这些数字更多地集中在运营时间。多个表,多个查询,可能有些通过联接释放,有些则没有。命中率最高(当时为270万)是从一个带有where子句,无联接的空表中进行的简单选择。我希望连接到空表的较大查询可能包括对链接表的更新,但是我将检查并尽快更新此问题。
更新:有1000个查询,执行计数在1043-4622614之间(超过2.5个月)。我将不得不挖掘更多信息以找出缓存计划的产生时间。这只是为了让您了解查询的范围。大多数都相当复杂,有20多个连接。
@ srutzky-是的,我相信会有一个与计划编制时间相关的日期栏,因此您将对此感兴趣,因此我将对其进行检查。我想知道,当SQL Server位于VMware群集上时,线程限制是否会成为一个因素?值得庆幸的是,即将成为专用的Dell PE 730xD。
@Frisbee-对不起,您的回复很晚。正如您所建议的,我使用SQLQueryStress在空表中对24个线程运行了10,000次select *(实际上是240,000次迭代),并立即达到10,000个批处理请求/秒。然后,我在24个线程中减少了1000次,并达到了4,000个批处理请求/秒以下。我还仅在12个线程上尝试了10,000次迭代(因此总共进行了120000次迭代),这产生了持续的6,505批/秒。实际上,对CPU的影响非常明显,在每次测试运行期间,约占CPU总使用量的5-10%。网络等待时间可以忽略不计(例如,工作站上的客户端需要3毫秒),但是对CPU的影响是肯定的,就我而言,这是非常确定的。这似乎归结为CPU使用率和一些不必要的数据库文件IO。每秒总执行次数约为3000次,这比生产中的要多,但是我只测试了数十个这样的查询之一。数百个查询以每分钟300-4000次之间的速率命中空表的最终结果在CPU时间方面不可忽略。所有测试都是针对具有双闪存阵列和256GB RAM,12个现代内核的空闲PE 730xD进行的。
@ srutzky-好主意。默认情况下,SQLQueryStress似乎使用连接池,但是无论如何,我发现,是的,连接池复选框已选中。更新以跟随
@ srutzky-应用程序上的连接池显然未启用-如果已启用,则无法使用。我进行了探查器跟踪,发现对于审计登录事件,连接具有EventSubClass“ 1-Nonpooled”。
RE:连接池-检查了weblogics,发现启用了连接池。针对活着的发现更多痕迹,发现池化迹象没有正确/根本没有:
这是当我对填充的表没有连接的情况下运行单个查询时的样子。异常显示为“与SQL Server建立连接时发生与网络有关或特定于实例的错误。找不到服务器或无法访问该服务器。请验证实例名称正确并且已将SQL Server配置为允许远程连接。 (提供程序:命名管道提供程序,错误:40-无法打开与SQL Server的连接)“请注意批处理请求计数器。在生成异常的时间内对服务器执行ping操作会成功执行ping响应。
更新-两次连续的测试运行,相同的工作量(select * fromEmptyTable),启用/未启用池。CPU使用率略高,故障很多,并且从未超过500个批处理请求/秒。测试显示10,000个批处理/秒,并且在启用池的情况下没有失败,大约400个批处理/秒,然后由于禁用了池而导致很多失败。我想知道这些故障是否与连接可用性不足有关?
@srutzky-从sys.dm_exec_connections中选择Count(*);
启用池化:即使在负载测试停止后也始终保持37
禁用池化:11-37,具体取决于是否
在SQLQueryStress 上发生异常,即:当这些低谷出现在Batchs
/ sec图上时,在SQLQueryStress上发生异常,并且
连接数下降到11,然后逐渐恢复到37当批次开始达到高峰且未发生异常时。非常非常有趣。
两个测试/活动实例上的最大连接数设置为默认值0。
已经检查了应用程序日志并且找不到连接问题,但是由于错误的数量和大小(即:大量的堆栈跟踪错误),只有几分钟的可用日志记录可用。应用程序支持的一位同事建议,发生大量与连接有关的HTTP错误。似乎基于此,由于某种原因,应用程序无法正确地建立连接池,结果服务器反复耗尽连接。我将进一步研究应用日志。我想知道是否有办法从SQL Server方面证明这种情况正在生产中发生?
@ srutzky-谢谢。我明天将检查weblogic配置并进行更新。我只是在考虑仅37个连接-如果SQLQueryStress在10,000次迭代中执行12个线程= 120,000个非池选择语句,那是否不应该意味着每个选择都将创建一个与sql实例的不同连接?
@ srutzky-将Weblogics配置为缓冲连接,因此它应该可以正常工作。在4个负载平衡的weblogic的每一个上,连接池都是这样配置的:
- 初始容量:10
- 最大容量:50
- 最小容量:5
当我增加执行从空表查询中执行选择的线程数时,连接数将达到47左右。在禁用连接池的情况下,我始终看到较低的最大批处理请求数/秒(从10,000降低到大约400)。每次将发生的情况是,SQLQueryStress上的“异常”在批处理/秒进入低谷后不久发生。它与连通性有关,但我无法确切说明为什么会这样。当没有测试在运行时,#connections下降到大约12。
在禁用连接池的情况下,我很难理解为什么会发生异常,但是也许这是Adam Machanic的其他所有stackExchange问题?
@srutzky我想知道为什么即使SQL Server没有用尽连接,异常也会在没有启用池的情况下发生?
SELECT COUNT(*) FROM sys.dm_exec_connections;
以查看启用缓冲池或启用缓冲池之间的值是否有很大差异。不。基于这些错误,我认为禁用池后会有更多连接。
Pooling=false
还是Max Pool Size
?