AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 123370
Accepted
Peter
Peter
Asked: 2015-12-11 02:37:28 +0800 CST2015-12-11 02:37:28 +0800 CST 2015-12-11 02:37:28 +0800 CST

应用程序查询空表

  • 772

我公司使用的应用程序存在相当大的性能问题。我正在处理的数据库本身存在许多问题,但其中许多问题纯粹与应用程序相关。

在我的调查中,我发现有数百万个查询命中查询空表的 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 集群上时,线程限制是否会成为一个因素?谢天谢地,很快就会成为专用的 Dell PE 730xD。

@Frisbee - 抱歉回复晚了。正如您所建议的,我使用 SQLQueryStress 在 24 个线程上从空表中运行了 select * 10,000 次(实际上是 240,000 次迭代)并立即达到 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 进行。 这是 SQLSentry 的输出

@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 上是否
    发生异常即:当 Batches
    /sec 图表上出现这些波谷时,SQLQueryStress 上发生异常,
    连接数下降到 11,然后逐渐回升到 37当批次开始达到峰值并且没有发生异常时。非常非常有趣。

两个测试/实时实例上的最大连接数设置为默认值 0。

已检查应用程序日志,但找不到连接问题,但是,由于错误的数量和大小很大,因此只有几分钟的日志记录可用,即:大量堆栈跟踪错误。一位应用程序支持同事建议,大量 HTTP 错误的发生与连接有关。似乎基于此,由于某种原因,应用程序未正确汇集连接,结果,服务器反复耗尽连接。我会更多地查看应用程序日志。我想知道是否有一种方法可以证明这种情况发生在 SQL Server 端的生产环境中?

@srutzky- 谢谢。我明天会检查 weblogic 配置并更新。我在考虑仅仅 37 个连接——如果 SQLQueryStress 在 10,000 次迭代中执行 12 个线程 = 120,000 个非池化的选择语句,难道这不意味着每个选择都创建一个到 sql 实例的不同连接吗?

@srutzky- Weblogics 配置为连接池,因此它应该可以正常工作。连接池的配置如下,在 4 个负载平衡的 weblogics 中的每一个上:

  • 初始容量:10
  • 最大容量:50
  • 最小容量:5

当我增加执行 select from empty table 查询的线程数时,连接数峰值约为 47。在禁用连接池的情况下,我始终看到较低的最大批处理请求/秒(从 10,000 下降到大约 400)。每次都会发生的是 SQLQueryStress 上的“异常”发生在 batches/sec 进入低谷后不久。它与连接性有关,但我不明白为什么会这样。当没有测试运行时,#connections 下降到大约 12。

禁用连接池后,我无法理解为什么会发生异常,但也许这是 Adam Machanic 的另一个 stackExchange 问题/问题?

@srutzky 我想知道为什么在没有启用池的情况下发生异常,即使 SQL Server 没有用完连接?

sql-server sql-server-2008-r2
  • 3 3 个回答
  • 612 Views

3 个回答

  • Voted
  1. Best Answer
    Solomon Rutzky
    2015-12-11T09:23:04+08:002015-12-11T09:23:04+08:00

    我怀疑发送请求、确认请求、处理请求、返回请求以及应用程序确认接收的实际机制本身会对性能产生影响。

    是的,甚至还有一些额外的因素,但如果不分析系统,就不可能说出这些因素中的任何一个实际影响您系统的程度。

    话虽这么说,你问的是什么可能是一个问题,有一些事情要提,即使其中一些目前不是你特定情况的一个因素。你说:

    我们有大约 300 个空表,其中一些表每分钟查询高达 100-200 次。

    • 未被查询的空表不是问题。但我想你的意思也可能是他们都在被询问,只是有些人受到的打击比其他人多得多。
    • 如果提交的查询文本在调用之间保持相同,那么查询解析和执行计划生成应该不是什么大问题。SQL Server 将散列查询文本并在计划缓存中查找它。如果找到,则它不会再次执行解析或编译步骤(直到从缓存中删除计划)。
    • 任何表,无论是空表还是非空表,都至少需要一个“共享”锁来表明该资源正在被使用。这可以防止需要独占锁的操作(添加/更改/删除列等)在资源正在使用时进行更改。由于没有数据,锁定和解锁即使在不到 1 毫秒的时间内完成,仍然需要系统资源(内存和 CPU)来管理这些锁定操作。
    • 即使没有结果集从 SQL Server 返回到应用程序,无论查询是否产生结果,仍然有相同数量的网络流量流向 SQL Server。需要发送查询文本或存储过程的名称。并且即使没有返回结果,SQL Server 仍然必须发送一些包含结果集结构的网络数据包以及告诉客户端结果集正在启动(即使没有找到行)然后结果集是结束,应该关闭。并且可能有来自打印语句和/或行计数的其他消息。
    • 连接到 SQL Server 需要一些系统资源。它需要 CPU 和内存来处理身份验证(以及来回的网络数据包),这也需要时间。这就是连接池存在的原因:减少这笔费用。
    • 即使连接池减少了系统资源的使用,SQL Server 仍然需要维护这些连接,这需要内存和一些最小的 CPU。
    • 即使没有行并因此执行时间非常快,查询仍会执行。即使有 10 或 10,000 行,并且由于它们被频繁使用而从缓冲池(即内存)中提取,线程仍然需要完成这项工作。处理这个无用查询的线程并没有处理实际有用的查询。

    可能还有更多,但这应该有助于了解事物。请记住,与大多数性能问题一样,这都是规模问题。如果每分钟被击中一次,上述所有项目都不是问题。这就像在您的工作站或开发数据库中测试更改:它总是只对表中的 10 - 100 行起作用。将该代码移至生产环境,运行需要 10 分钟,有人肯定会说:“好吧,它在我的盒子上运行”;-)。意思是,只是由于拨打的电话数量过多,您才会看到问题,但这就是存在的情况。

    因此,即使有 100 万个无用的 0 行查询,也等于:

    • 额外的 200 万次锁操作(每个锁都必须解锁,对吧?)。这主要是花费在无用操作而不是有用操作上的时间成本。
    • 更多的网络流量可能会让你更接近饱和(不确定这有多大可能,但仍然)
    • 维护的连接越多,占用的内存就越多。您有多少未使用的物理 RAM?该内存将更好地用于运行查询和/或查询计划缓存。最坏的情况是您的物理内存不足并且 SQL Server 必须开始使用虚拟内存(交换),因为这会减慢速度(检查您的 SQL Server 错误日志以查看您是否收到有关内存被分页的消息)。

      以防万一有人提到,“好吧,有连接池”。是的,这绝对有助于减少所需的连接数。但是,由于查询以每分钟多达 200 次的速度传入,因此存在大量并发活动,合法请求仍需要存在连接。执行 aSELECT * FROM sys.dm_exec_connections;以查看您维护的活动连接数。

    • 无论如何,每天至少有 100 万次线程本可以做一些有用的事情却不可用。

    如果我在这里所说的没有错,那么在我看来,即使是小规模的,这也是对您系统的一种 DDoS 攻击,因为它正在用虚假请求淹没网络和您的 SQL Server ,防止真正的请求到达 SQL Server 或被 SQL Server 处理。

    • 7
  2. paparazzo
    2015-12-11T11:04:21+08:002015-12-11T11:04:21+08:00

    如果表格每分钟被点击 100-200 次,那么它们(希望)在内存中。服务器上的负载非常非常低。除非数据库服务器上有高 CPU 或内存,否则这可能不是问题。

    是的,查询采用共享锁,但希望它们不会阻止任何更新锁,也不会被任何更新锁阻止。您是否对这些表进行了任何更新、插入或删除。如果不是,我会放手 - 如果您遇到性能问题,那么从数据库服务器的角度来看,必须有更大的鱼要炸。

    我在一个空表上对 100,000 个 select count(*) 进行了测试,它在 32 秒内运行并且查询是通过网络进行的。所以 1/3 毫秒。除非您的网络超载,否则这甚至不会影响客户端。如果您遇到重大性能问题,这些 1/3 毫秒的空白查询并不是导致应用程序崩溃的原因。

    这些可能只是左连接的一部分,用于获取一些不属于当前应用程序的静态类型数据。它可以与其他查询链接在一起,因此它不是额外的往返。如果是的话,它很草率,但它甚至不会造成更多的流量。

    所以回头看看实际的陈述。您是否看到这些表有任何更新、添加或删除?

    是的,许多空表和对空表的查询都表明编码草率。但是,如果您遇到重大性能问题,这不是原因,除非您还对这些表进行了一些非常草率的写操作。

    • 1
  3. alonk
    2015-12-11T05:55:18+08:002015-12-11T05:55:18+08:00

    通常在每个查询上完成以下步骤:

    1. 来自应用程序的请求。
    2. 数据库解析查询。
    3. 数据库引擎检查此查询是否已存储在 RAM 中。如果内存中存在,则使用执行计划。
    4. 如果 RAM 中不存在,数据库引擎检查查询中对象的现有统计信息并确定执行计划。
    5. 运行执行计划,使用i/o从磁盘获取数据。
    6. 对申请的回应。

    您提到的许多查询可能会给已经很重的系统带来额外的负载——连接、CPU、RAM 和 I/O 的额外负载。

    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve