【问题标题】:SQL SERVER Procedure Inconsistent PerformanceSQL SERVER 过程不一致的性能
【发布时间】:2010-12-04 01:10:37
【问题描述】:

我正在处理一个涉及 5 个过程、几个 while 循环以及大量插入和更新的 SQL 作业。

此作业处理大约 75000 条记录。

现在,这项工作可以正常处理 10000/20000 条记录,速度约为 500/分钟。在大约 20000 条记录之后,执行就结束了。它每 30 分钟加载大约 3000 条记录,并保持相同的速度。

我怀疑网络,但不确定。这类查询很难通过 SQL 性能监视器进行分析。不太确定从哪里开始。

此外,在其中一个 procs 中有一个游标,它只针对很少的记录执行。

关于如何在全尺寸数据集上加快此过程的任何建议?

【问题讨论】:

  • 如果不访问代码(甚至更好:访问数据库),这种事情很难诊断。你能分享更多信息吗?
  • 您正在开始交易吗?您是否有许多可能会影响性能的索引?
  • 目前只有一个事务,但我也计划将事务添加到内部过程调用中。事务对性能有影响吗?
  • 整个过程大约使用了10张表,涉及的索引很多。但不能说哪个可能会影响性能。但同样,为什么前 20,000 条记录没有发生这种情况,是不是每次执行查询时都会缓存一些东西,在 1000 秒后堆积起来,从而降低性能?
  • @Joel:我想我解释了基本流程以及正在使用的高级对象和机制。如果您需要任何具体信息,请告诉我。谢谢。

标签: sql sql-server sql-server-2005 tsql performance


【解决方案1】:

我会检查您的更新是否在交易中。如果是,它可以解释为什么它会在一定数量的“修改”数据后死亡。你可以检查你的“tempdb”有多大作为一个指标。

我还看到在长时间运行的事务期间,当同时有其他“使用”时,数据库会死掉,这也是因为使用了事务性和不正确的隔离级别。

如果您可以将您的工作拆分为独立的非重叠块,您可能希望这样做:例如按日期、“根”对象的 ID 范围等分块完成工作。

【讨论】:

  • 谢谢范...这是我一直在寻找的东西...我会检查并回复您我相信问题是我使用单个事务处理所有 75K 记录...也许我应该把它改成更小的块......
  • @van:我尝试使用 EXEC sp_helpdb 'tempdb' 发现 db_size 为 1587.88,而该作业以大约 35 k 记录运行(低性能)....我终止了事务并回滚更改,然后再次检查。 tempdb 使用的空间仍然相同。我不确定我是否知道我在寻找什么改变?
  • 这对于 tempdb 的大小绝对没有问题,因此您似乎对其他事务没有问题。你自己的过程似乎是一个矫枉过正。尝试将你的大工作分成几块,看看它是否更快(比如 10K 行,然后是 20K,然后是 50K - 看看性能是否是非线性的)。但请提供有关您正在做什么的更多信息 - 可能会有更好的解决方案来完成您的任务。
  • 我想拆分应该会有所帮助,因为在前 10K 到 20K 记录之前性能很好,但我最好一次性处理所有内容....我尝试在下面解释我的过程...发布了单独的答案出于格式原因。
  • 恕我直言,只要您没有其他事务同时在您的数据库上工作,您应该可以处理长时间运行的事务。如果没有,这是您的 tempdb 变得相当大的时候,这不是一个好兆头。您可能还想在作业运行时检查是否有任何对象锁。
【解决方案2】:

我怀疑你的整个过程有缺陷。我导入了一个包含 20,000,000 条记录的数据文件,并访问了更多的表,并且在比您描述的 75000 条记录的时间更短的时间内完成了一些非常复杂的处理。记住循环和使用游标一样糟糕。

我认为,如果您将其设置为 SSIS 包,您可能会惊讶地发现整个程序可以在几分钟内运行。

根据您当前的设置,请考虑临时数据库中的空间是否不足,或者它可能正在尝试增长但增长速度不够快。还要考虑在减速开始时,是否有其他正在运行的作业可能导致阻塞?还可以摆脱循环并以基于集合的方式处理事物。

【讨论】:

  • 感谢 HLGEM!摆脱循环是我尝试的第一件事,但在这种情况下这是不可能的。根据每条记录,我需要从大量现有表中获取数据,根据记录是否存在执行验证和插入/更新,并将状态更新回输入表。使用 SSIS 创建可能更容易,但它不会摆脱循环。我在不同的时间执行了工作,包括周末,而且大多数情况下没有任何额外的工作在运行。
【解决方案3】:

好的...所以我正在逐步执行以下操作:

  1. 在 TEMP 表中加载文件,只是一个中介。
  2. 使用基于 SET 的事务对所有记录进行一些验证。
  3. 现在开始实际处理。

交易从这里开始......

循环从这里开始

a. Pick Records based in TEMP tables PK (say customer A).

b. Retrieve data from existing tables (e.g. employer information)

c. Validate information received/retrieved.

d. Check if record already exists - UPDATE. else INSERT. (THIS HAPPENS IN SEPARATE PROCEDURE)

e. Find ALL Customer A family members (PROCESS ALL IN ANOTHER **LOOP** - SEPARATE PROC)

f. Update status for CUstomer A and his family members.

循环到此结束

交易到此结束

【讨论】:

  • 你说摆脱循环是不可能的。但是,我会质疑这种说法。在 SQL 中,从循环到基于集合的某种改进是不可能的,这是一件非常罕见的事情。老实说,您描述的场景听起来很可能消除一些循环。为什么步骤 e 涉及循环?如果由于某些分层数据结构而需要循环,为什么不能一次为一整组客户执行循环,而不是为每个客户执行多次?这只是可以进行更改的一个示例。
猜你喜欢
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 2016-04-14
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
相关资源
最近更新 更多