Pet*_*ter 10 performance sql-server sql-server-2008-r2
我的公司使用的应用程序存在严重的性能问题。我正在解决的数据库本身存在许多问题,但许多问题纯粹与应用程序有关。
在我的调查中,我发现有数百万个查询访问 SQL Server 数据库,这些查询查询空表。我们有大约 300 个空表,其中一些表每分钟查询 100-200 次。这些表格与我们的业务领域无关,本质上是原始应用程序的一部分,供应商在与我公司签订合同为我们提供软件解决方案时并未删除这些原始应用程序。
除了我们怀疑我们的应用程序错误日志充斥着与此问题相关的错误这一事实之外,供应商向我们保证,应用程序或数据库服务器不会对性能或稳定性产生影响。错误日志泛滥到我们无法看到超过 2 分钟的错误进行诊断的程度。
就 CPU 周期等而言,这些查询的实际成本显然会很低。但是有人可以建议对 SQL Server 和应用程序产生什么影响吗?我怀疑发送请求、确认请求、处理请求、返回请求和确认应用程序接收的实际机制本身会对性能产生影响。
我们为应用程序使用 SQL Server 2008 R2、Oracle Weblogic 11g。
@Frisbee- 长话短说,我创建了一个包含查询文本的表,该表命中了应用程序数据库中的空表,然后查询它以查找我知道为空的所有表名,并得到了一个很长的列表。最重要的是在 30 天的正常运行时间内执行了 270 万次,请记住,该应用程序通常在上午 8 点至下午 6 点使用,因此这些数字更集中于运行时间。多个表,多个查询,可能有些是通过连接相关的,有些则不是。最大的成功(当时是 270 万)是从一个带有 where 子句的空表中进行简单的选择,没有连接。我希望连接到空表的更大查询可能包括对链接表的更新,但我会检查并尽快更新这个问题。
更新:有 1000 个查询的执行计数在 1043 - 4622614 之间(超过 2.5 个月)。我将不得不进一步挖掘以找出缓存计划的来源。这只是为了让您了解查询的范围。大多数都相当复杂,有 20 多个连接。
@srutzky-是的,我相信有一个与计划何时编译相关的日期列,因此我会感兴趣,所以我会检查一下。我想知道当 SQL Server 位于 VMware 集群上时,线程限制是否会成为一个因素?谢天谢地,很快就会成为专用的戴尔 PE 730xD。
@Frisbee - 抱歉回复晚了。正如您所建议的,我使用 SQLQueryStress(实际上是 240,000 次迭代)在 24 个线程上从空表中运行了 10,000 次 select * 并立即达到了 10,000 批请求/秒。然后我将 24 个线程减少到 1000 次,并达到了不到 4,000 个批处理请求/秒。我还仅在 12 个线程上尝试了 10,000 次迭代(因此总共 120000 次迭代),这产生了持续的 6,505 批次/秒。对 CPU 的影响实际上很明显,每次测试运行期间大约占 CPU 总使用量的 5-10%。网络等待时间可以忽略不计(比如我工作站上的客户端需要 3 毫秒),但 CPU 影响肯定存在,就我而言,这是非常确定的。这似乎归结为 CPU 使用率和一些不必要的数据库文件 IO。每秒总执行次数不到 3000,这不仅仅是在生产中,但是我只测试了几十个这样的查询中的一个。因此,当涉及到 CPU 时间时,数百个查询以每分钟 300-4000 次的速度命中空表的净影响是不可忽略的。所有测试均针对具有双闪存阵列和 256GB RAM、12 个现代内核的空闲 PE 730xD 完成。
@srutzky-好想法。SQLQueryStress 似乎默认使用连接池,但我还是看了看,发现是的,选中了连接池框。更新跟随
@srutzky- 应用程序显然未启用连接池 - 或者,如果启用,则它不起作用。我做了一个探查器跟踪,发现连接有 EventSubClass "1 - Nonpooled" for Audit Login 事件。
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上是否发生异常,即:当这些低谷出现在
批处理/秒图上时,SQLQueryStress 上发生异常
,连接数下降到 11,然后逐渐回升到 37当批次开始达到峰值并且没有发生异常时。非常非常有趣。
测试/实时实例上的最大连接数均设置为默认值 0。
已检查应用程序日志并找不到连接问题,但是由于错误的数量和大小(即:大量堆栈跟踪错误),只有几分钟的可用日志记录。应用支持部门的一位同事表示,发生了大量与连接相关的 HTTP 错误。似乎基于此,由于某种原因,应用程序没有正确地汇集连接,结果,服务器反复耗尽连接。我会更多地查看应用程序日志。我想知道有没有办法证明这在 SQL Server 端的生产中发生?
@srutzky-谢谢。我明天会检查 weblogic 配置并更新。我在考虑仅仅 37 个连接 - 如果 SQLQueryStress 在 10,000 次迭代中执行 12 个线程 = 120,000 个非池化的 select 语句,这不应该意味着每个 select 都会创建一个到 sql 实例的不同连接吗?
@srutzky- Weblogics 配置为池连接,因此它应该可以正常工作。连接池配置如下,在 4 个负载均衡的 weblogics 上:
当我增加执行 select from empty table 查询的线程数时,连接数在 47 左右达到峰值。禁用连接池后,我始终看到较低的最大批处理请求/秒(从 10,000 下降到大约 400)。每次都会发生的是 SQLQueryStress 上的“异常”在批次/秒进入低谷后不久发生。它与连接性有关,但我无法理解为什么会发生这种情况。当没有运行测试时,#connections 会下降到大约 12。
禁用连接池后,我无法理解为什么会发生异常,但对于 Adam Machanic 来说,这可能是另一个 stackExchange 问题/问题?
@srutzky 我想知道为什么在没有启用池的情况下会发生异常,即使 SQL Server 没有用完连接?
我怀疑发送请求、确认请求、处理请求、返回请求和确认应用程序接收的实际机制本身会对性能产生影响。
是的,甚至还有一些额外的因素,但如果不分析系统,就不可能说这些因素中的任何一个实际影响您的系统的程度。
话虽如此,您正在询问什么可能是问题,并且有一些事情要提及,即使其中一些目前不是您特定情况的一个因素。你说:
我们有大约 300 个空表,其中一些表每分钟查询 100-200 次。
甚至可能还有更多,但这应该有助于了解事物。请记住,与大多数性能问题一样,这都是规模问题。如果每分钟被击中一次,上面提到的所有项目都不是问题。这就像在您的工作站或开发数据库中测试更改:它始终只处理表中的 10 - 100 行。将该代码移至生产环境,运行需要 10 分钟,有人肯定会说:“好吧,它适用于我的机器”;-)。意思是,这只是由于拨打的电话数量庞大,您才看到问题,但这就是存在的情况。
因此,即使有 100 万次无用的 0 行查询,也相当于:
维护更多连接,占用更多内存。你有多少未使用的物理内存?该内存将更好地用于运行查询和/或查询计划缓存。最坏的情况是物理内存不足,SQL Server 必须开始使用虚拟内存(交换),因为这会减慢速度(检查 SQL Server 错误日志以查看是否收到有关内存被分页的消息)。
以防万一有人提到,“好吧,有连接池”。是的,这绝对有助于减少所需的连接数量。但是随着查询以每分钟高达 200 次的速度进入,这意味着大量的并发活动和合法请求仍然需要存在连接。执行 aSELECT * FROM sys.dm_exec_connections;
以查看您维护的活动连接数。
如果我对我在这里所说的没有错误,那么在我看来,即使是小规模的,这也是对您系统的一种 DDoS 攻击,因为它用虚假请求淹没了网络和您的 SQL Server ,防止真正的请求到达 SQL Server 或被 SQL Server 处理。
归档时间: |
|
查看次数: |
525 次 |
最近记录: |