【问题标题】:How to improve performance of writing to database in MVC5?如何提高在 MVC5 中写入数据库的性能?
【发布时间】:2015-02-18 17:22:05
【问题描述】:

我有一个 MVC5 应用程序,我正在使用 Azure 的 EF6 和 MySQL 数据库服务,即 CleanDB MySQL。我有一个 CSV 阅读器类,它在我的控制台应用程序中运行得非常快。然后,在我的 MVC 应用程序中,我有一个这样的模型:

Provider.cs

public class Provider
{
    public int ProviderId { get; set; }

    public string ProviderName { get; set; }

    public string Email { get; set; }

    public string Address { get; set; }

    public string City { get; set; }

    [ForeignKey("State")]
    public int StateID { get; set; }

    public virtual State State { get; set; }

    public string Zip { get; set; }

    public string Phone { get; set; }

    public string Fax { get; set; }

    public string SICCode { get; set; }

    public string Description { get; set; }

    public string Website { get; set; }

    public string RefId { get; set; }
}

然后,在我的 Configuration.cs 文件中,我有这样的内容:

string[] csvs = Directory.GetFiles(@"C:\Users\User\Downloads\db\test\");

foreach (string csv in csvs)
{
    using (CsvReader reader = new CsvReader(csv))
    {
        foreach (string[] values in reader.RowEnumerator)
        {
            var provider = new Provider();
            provider.ProviderName = values[0];
            provider.Email = values[1];
            provider.Address = values[2];
            provider.City = values[3];
            provider.StateID = 491;
            provider.Zip = values[5];
            provider.Phone = values[6];
            provider.Fax = values[7];
            provider.SICCode = values[8];
            provider.Description = values[9];
            provider.Website = values[10];
            provider.RefId = "";

            context.Providers.Add(provider);
        }
    }
}

context.SaveChanges();

关键是我有大约 50 个 CSV 文件,总大小为 400MB,总条目数约为 900 万。出于测试目的,我使用了列表中最小的 CSV 文件,它是一个 2MB 的文件,大约有 15k 个条目。执行Update-Database 花了大约 40 分钟将所有这些条目放入数据库。你可以假设我需要多少时间来处理 900 万个条目。知道如何加快这个过程吗?

【问题讨论】:

  • 您应该尝试不同的方法。可能 EF 不是海量数据加载的最佳工具。 Look herehere
  • 您的仪器在哪里显示所花费的时间? IE,我假设您的日志记录解决方案应用了时间戳,那么根据这些时间戳,您正在执行的最昂贵的操作是什么?当涉及到性能问题时,衡量衡量衡量!
  • 史蒂夫做对了。 EF 不适用于批量操作(大量导入/导出)。每个数据库都有它自己的功能。例如,MSSQL 使用 BCP。

标签: mysql asp.net-mvc entity-framework csv azure


【解决方案1】:

您确定问题出在您的数据库性能上吗?通过直到最后才调用SaveChanges,Entity Framework 将所有内容批处理在一个事务中,因此除了传输时间之外,您只需将 900 万个条目添加到任何数据库表的标准成本。除了为您的数据库服务器提供更多资源之外,您对此无能为力,这可能会或可能不会产生影响,具体取决于它当前的资源限制程度。即使在最坏的情况下,实际查询的传输时间也不应该超过一秒,除非您只是拥有世界上最差的连接或试图通过拨号或其他方式进行此操作。

您最大的性能影响可能是实际访问文件系统并读取 CSV 文件。我会仔细查看您的CSVReader,看看您是否可以找到性能更高的替代品。另外,我不确定这个库是如何工作的,但如果它从文件系统中流式传输文件,最好一次将它全部读入内存(假设你有足够的 RAM)。访问驱动器上的许多小型集群通常比读取单个大型集群要慢。一个非常粗略的类比可能是将文件复制到 USB 驱动器(因为这是我们几乎所有人都有经验的东西)。我相信您已经注意到复制 4000 个 1KB 文件比复制一个 4 MB 文件花费的时间要长得多,并且只能从那里扩展。

【讨论】:

  • 我尝试创建一个控制台应用程序,其中我有 List<string> all = new List<string>(); 并从我最小的 CSV 文件 (all.Add(values[i]);) 中放入所有行的所有列值,并在大约 1 秒内完成使用我的 CSV 阅读器,当我执行 all.Count 之类的操作时,列表中有大约 160k 个条目,我猜这是正确的。看来我的 CSV 阅读器在阅读时做得很好。
  • 不从内存中读取。任何事情都会像那样表现得很好。我说的是从文件系统中读取。
  • 我的意思是,我的代码与我从计算机中的 CSV 文件中读取的上述代码完全相同,除了创建新的 Provider 并为其分配值之外,我创建了一个 List<string> ,并在那里分配值。任何可以帮助我的代码?我不能这样做MySqlBulkLoad,而只要我知道 CleanDB MySQL 出于安全考虑不允许这样的事情。
猜你喜欢
  • 1970-01-01
  • 2016-12-25
  • 2011-01-01
  • 2014-05-15
  • 1970-01-01
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多