【问题标题】:TIMEOUT issue while searching data from SQL Server when insert update commands being executed执行插入更新命令时从 SQL Server 搜索数据时出现超时问题
【发布时间】:2017-08-04 16:28:18
【问题描述】:

我有一个用 C# 开发的 Windows 服务。此服务将 XML 文件中的数据导入 SQL Server 数据库中的不同表中。这些 XML 文件很大。一个 500 MB 大小的特定文件需要 1 个多小时才能导入到具有数百万行的表中。

我有一个用 ASP.NET MVC 开发的 web 应用程序,上面的数据库在这个应用程序的后端。此应用程序通过从该数据库的表中过滤相关记录来显示不同的报告。此应用程序还可以处理记录。

当我在 Windows 服务导入 XML 文件期间运行应用程序与数据库交互时,我的 Web 应用程序挂起,并且在很长一段时间后发生超时错误。

我在 Windows 服务的存储过程中使用简单的插入更新命令,这些存储过程中没有事务。

请提供任何解决方案以避免此问题。

【问题讨论】:

  • 第一件事 - 一次处理大数据是个坏主意。我要做的第一件事就是重新设计系统以分块导入数据。
  • 您应该考虑使用后台任务,这些任务在后台处理您的大导入并且不中断应用程序的主线程。

标签: c# sql sql-server model-view-controller


【解决方案1】:

如果您运行的是 SQL Server 企业版,则应该利用 Table Partitioning。您可以做的,特别是数据加载,将数据加载到临时表中,然后将分区切换到最终表中。这将在加载过程中消除最终表上的任何表级锁定,以便您的报告可以在加载发生的同时运行。不过,这里的副产品是,在加载过程完成并切换分区之前,报告将无法查看正在加载的数据。

您需要正确设计它,因为它取决于多种因素,我不会在这篇文章中深入探讨其中的细微差别,但是您可以找到许多关于此的博客:@ 987654322@ 供您参考。

【讨论】:

    【解决方案2】:

    您可以在配置文件中增加最大连接数。这是我的配置文件:

    <connectionStrings>
    <add name="local" connectionString="user id=sa;password=test+;Data Source=    (local);Max Pool Size=500;Pooling=true;Database=user"   providerName="System.Data.SqlClient" />
    </connectionStrings>  
    

    我已设置 Max Pool Size=500

    【讨论】:

      【解决方案3】:

      任何 SQL Server INSERTUPDATE 命令在事务中运行 - 无论您是否指定。如果您自己不指定任何内容,SQL Server 将使用隐式事务来确保语句的数据完整性。

      默认情况下,SQL Server 使用行级锁,例如它只锁定正在插入或更新的行。但是,如果该事务会影响超过 5000 行,则 SQL Server 将执行 锁升级 并用 全表排他锁 替换 5000 个单独的行级锁,直到操作已完成并且事务已提交(或回滚)。

      在此期间,没有其他操作 - 甚至 SELECTs 都不可能针对该表...。

      唯一的解决方案是在没有其他操作对数据库运行的时候运行这些导入,或者将这些插入拆分为可以单独提交的少于 5000 行的较小块。

      【讨论】:

        【解决方案4】:

        你可以像这样增加命令时间

        cmd.CommandTimeout = 3600; // in seconds
        

        您还必须查看存储过程为什么会超时 您的查询在某些地方中断了

        【讨论】:

          【解决方案5】:

          我可以根据我的经验提出一些建议。

          首先,不建议在单个事务中推送 500MB 的全部数据。

          然后进行必要的保存点,如果所有事务都成功,则最后提交。

          因为长时间持有连接对象是不可取的。如果您仍然需要,可以尝试增加 sql server 超时时间。但这是一种不好的方法。

          最好是拆分 xml 内容并尝试使用保存点并最终提交所有事务。

          不要以为你只是在做一个简单的插入或更新命令。如果您的列上有索引,那么这么多记录将需要很长时间。

          确保您拥有正确的索引并且只有必要的索引。

          如果您还有其他问题,请在此处回复。您在当前代码中使用的方法是什么?

          【讨论】:

            【解决方案6】:

            你应该试试 with(nolock) 选项。 This SO 提供有关 Nolock 的详细信息。如果您使用的是 EntityFramework 之类的 ORM,那么我们需要仔细查看代码。

            【讨论】:

            • NOLOCK 提示不是并发问题的解决方案。
            • 它不是一个 opt 解决方案,但以上都不是 OP 的快速解决方案。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-03-28
            • 2018-05-19
            • 2020-10-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多