【问题标题】:Why is this sql script so slow in SQL Server Management Studio?为什么这个 sql 脚本在 SQL Server Management Studio 中这么慢?
【发布时间】:2010-11-06 06:34:02
【问题描述】:

我有一个将大约 8000 行插入到 TABLE 变量中的 SQL 脚本。

插入该变量后,我使用 WHILE 循环遍历该表并执行其他操作。那个循环大概有 60 行代码。

如果我运行脚本的 TABLE 变量插入部分,没有 while 循环,大约需要 5 秒。太好了。

但是,如果我运行整个脚本,大约需要 15 分钟。

以下是有趣的和我想不通的:

当我运行整个脚本时,直到脚本进入几分钟后,我才看到任何打印语句。

然后,一旦它确定了要做什么(大概),它就会将插入操作运行到表 var 中,执行循环,这一切都进行得相当快。

然后,在循环结束时,或者甚至在循环结束后,它会等待并挂起更多分钟。最后,它会遍历循环之后脚本的最后几行左右。

我可以计算插入过程中花费的所有时间,然后是循环中花费的所有时间。但我不明白为什么它在脚本之前和结尾处似乎挂了这么多分钟。

为了踢球,我在插入临时表之后添加了一个 GO 语句,到那时为止的所有内容都按照您的预期运行;但是,我不能这样做,因为我需要那个变量,而 GO 语句显然会杀死那个变量。

我相信我将停止使用 table 变量并使用真实的表,以便我可以发出 GO,但我真的很想知道这里发生了什么。

您对 SQL Server 在此期间的工作有何想法?

谢谢!

【问题讨论】:

  • 能否提供脚本?不仔细研究就很难回答。
  • 我可以,但它有@17000 行长!不过我会编辑并发布相关位
  • 知道了……问题不在于插入或循环……而是循环之后的部分。我不知道为什么 sql server 花了这么长时间,但是一旦我摆脱了它(这是一个我重构的大“IN”语句),一切都很好。

标签: sql sql-server-2008


【解决方案1】:

您始终可以从Activity Monitorsys.dm_exec_requests 视图中检查脚本正在执行的操作。该脚本将被 something 阻止,您将能够在 wait_typewait_resource 列中看到阻止的内容。

有几个可能的罪魁祸首,比如等待行锁或表锁,但从问题的描述我怀疑是数据库或日志增长事件。一旦数据库足够大并且默认的 10% 增加意味着 GB 的增长,这些往往会非常昂贵。如果是这种情况,请尝试将数据库预先设置为所需的大小,并确保为数据文件启用了Instant File Initialization

【讨论】:

  • 查看this 的帖子,同一作者。
【解决方案2】:

PRINT 是缓冲的,因此您无法根据它们判断性能。
使用RAISERROR ('Message', 0, 1) WITH NOWAIT 立即查看输出。

要了解进程在做什么,我首先会调用sp_who2 几次并查看感兴趣进程的值:它是否被阻塞,等待类型是什么,如果有的话,以及很快。此外,仅查看服务器硬件负载(CPU、磁盘活动)可能会有所帮助(除非有其他活动进程)。

请发布一些代码。表 var 定义和循环就足够了,我相信,不需要 INSERT 的东西。

【讨论】:

    【解决方案3】:

    如果你使用的是table变量,可以试试用temp table代替它,看看性能有没有变化?

    如果可能,请发布代码,以便分析可能感兴趣的领域。

    【讨论】:

      【解决方案4】:

      从您问题的措辞看来,您似乎是在使用光标在表格中循环。如果是这种情况,在开始循环之前发出“SET NOCOUNT ON”命令会有所帮助。

      在之前的答案中提到了 table 变量,但作为一般规则,如果您有超过几行,您应该真正使用临时表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-12
        • 2018-10-08
        • 2014-04-15
        • 1970-01-01
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        相关资源
        最近更新 更多