远程SQL Server数据库中的.NET慢插入

时间:2016-01-20 22:55:52

标签: c# .net sql-server database entity-framework

我开发了一个客户端.NET WinForms应用程序。此应用程序用于使用数千条记录填充数据库。对于数据层,我使用了EF6。

当我在本地工作并运行应用程序时,每件事都按预期工作。插入速度非常快(约2分钟内超过500000条记录)。

现在我试图在托管服务器上使用远程数据库,我注意到插入速度非常慢(大约2分钟内少于500条记录)。这意味着比本地慢1000倍。

如果我尝试使用SQL Server Management Studio在远程数据库中插入500条记录,则操作将在不到1秒的时间内完成。

我的客户端应用程序出现了问题吗?

这里的插入功能:

public void SetDemoDimCustomer()
{
        DWContext dc = null;

        try
        {
            dc = DWContext.Create(SqlServerInstance, DbName);
            dc.Configuration.AutoDetectChangesEnabled = false;

            dc.Database.ExecuteSqlCommand("DELETE FROM DimCustomer");
            dc.Database.ExecuteSqlCommand("DBCC CHECKIDENT ('DimCustomer', RESEED, 0)");

            DimCustomer objCustomer;
            List<DimCustomer> lstDemoCustomers = new List<DimCustomer>();
            int length = 100;

            for (int i = 0; i < length; i++)
            {
                objCustomer = new DimCustomer();
                objCustomer.Name = "Customer " + (i + 1);
                objCustomer.CustomerBKey = (i + 1).ToString();

                lstDemoCustomers.Add(objCustomer);
            }

            dc.DimCustomer.AddRange(lstDemoCustomers);
            dc.SaveChanges();
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (dc != null)
            {
                dc.Dispose();
            }
        }
    }

我尝试使用Linq-to-SQL而不是EF6,但结果是一样的。也许不是特定的EF6问题。

有关远程系统的一些信息:

  • 操作系统:Windows Server 2012
  • RDBMS:SQL Server 2014 Express

提前致谢。

使用BULKINSERT进行某些测试后更新

好的,这是我第一次使用BulkInsert测试的结果:

  • 100条记录 - &gt; EF6 AddRange:9秒。 / EF6 BulkInsert:1秒
  • 1000条记录 - &gt; EF6 AddRange:1:27分钟。 / EF6 BulkInsert:1秒。 (哇!)
  • 10000条记录 - &gt; EF6 AddRange:14:39分钟。 / EF6 BulkInsert:4秒。 (wooooow!)

现在,当然,EF6 BulkInsert包是我项目的一部分。

2 个答案:

答案 0 :(得分:5)

Looks like most time is spend on the network waiting for a round-trip to complete. EF cannot be made to batch inserts (yet). So you cannot use EF for inserts here.

Investigate the typical solutions to this problem (TVPs and SqlBulkCopy).


The dispose pattern you are using is not a good choice. Just wrap dc in ´using` and delete all exception handling.

答案 1 :(得分:3)

正如所建议的那样,SqlBulkCopy是你最好的选择,但有一个有趣的Nuget包为实体框架做BulkInsert

https://efbulkinsert.codeplex.com/