(实体框架)集团 - 低绩效

时间:2016-03-26 10:05:30

标签: c# performance entity-framework sqlite linq-to-sql

我对实体框架的性能有一个非常特殊的问题。我使用SQLite提供程序的框架版本7(均来自nuget)。数据库有大约1000万条记录,但未来将有大约1亿条记录。 db的构造非常简单:

Cross-Origin Request Blocked: 
The Same Origin Policy disallows reading the remote resource at http://api.server.com/. 
(Reason: CORS preflight channel did not succeed).

我尝试按频道对事件进行分组,然后将它们总结为频谱。当我使用linq2sql时,我的性能非常低。对于10米的记录,查询大约需要15分钟并获得大约1 GB的RAM然后抛出OutOfMemoryException - 我认为Entity Framework将所有记录作为对象加载到内存中 - 但为什么呢?另一方面,简单的SQL需要大约3秒钟,并且不需要大量的RAM。

public class Sample
{
    public int SampleID { get; set; }
    public long Time { get; set; }
    public short Channel { get; set; } /* values from 0 to 8191, in the presented test 0-15 */
    public byte Events { get; set; } /* 1-255 */
}

public class Channel
{
    public int ChannelID { get; set; }
    public short Ch { get; set; }
    public int Es { get; set; }
}

public class MyContext : DbContext
{
    // This property defines the table
    public DbSet<Sample> Samples { get; set; }
    public DbSet<Channel> Spectrum { get; set; }

    // This method connects the context with the database
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = "E://database.db" };
        var connectionString = connectionStringBuilder.ToString();
        var connection = new SqliteConnection(connectionString);

        optionsBuilder.UseSqlite(connection);
    }
}

有什么建议吗?感谢您的帮助;)

2 个答案:

答案 0 :(得分:0)

建议? IGNORE ENTITY FRAMEWORK。

如同:这完全不是EF问题,甚至都不好笑。

查看EF发出的SQL,然后从该级别进行优化。哦,你对SQL的影响很小;但对于像这样的简单陈述,SQL将是最佳的。

什么不是最优的 - 并且有一个你从未看过SQL的提示 - 是数据库。这些指数在那里吗?代码首先令人惊讶,因为它对数据库的复杂性一无所知,你需要从“我的数据库最优”中首先查看它。指数。而且 - 遗憾的是 - 硬件。如果你达到1亿行,你需要掌握数据库中的权力来处理这个问题。

  

我认为Entity Framework将所有记录作为对象加载到内存中 -   但为什么呢?

性能dbugging中的规则1:不要认为 - 检查。查看生成的SQL(日志,res1变量可以显示)并查看提交给数据库的内容。

你可能只有那么多数据。你没有说有多少通道存在 - 这可能需要更大的机器。

检查一下。

另外:除非你需要,否则将结果拉入数组并不是很明智。在这种情况下,数组是内存问题(重新分配以获得大小),LIST可能更好(使用更多内存但不需要重新分配)。但是,一般而言,您希望避免实现结果集 - 即从可枚举中开始工作。并非总是如此,但您的测试可能只是简单地显示了问题。得到的数组可能是休。并且需要一块记忆。

严肃地说,质疑您选择的数据库技术。 SqlLite很不错 - 它很小,很轻巧。它在记忆中。它不适用于大量数据,它不是一个完整的数据库服务器。使用Sql Express可能会好得多(如果有的话:SQL express将使用内存进行缓存,而不是在你的进程中但是分开)。我个人不会将SqlLite用于可能使用数亿条记录的东西。

另外:注意你的SQL不同。 EF部件有一个OrderBy(不需要),SQL不是。订购可能很昂贵。这让我们回到“获取实体框架生成的SQL”。

答案 1 :(得分:-1)

问题与SQLite提供商有关。更改为SQL Server Compact后,一切正常;)