【发布时间】:2016-03-26 10:05:29
【问题描述】:
我对实体框架的性能有一个非常特殊的问题。我将框架的第 7 版与 SQLite 提供程序一起使用(均来自 nuget)。数据库有大约 1000 万条记录,但未来将有大约 1 亿条记录。 db的构建很简单:
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);
}
}
我尝试按频道对事件进行分组,并将它们汇总为频谱之类的东西。当我使用 linq2sql 时,我的性能非常低。对于 10m 的记录,查询大约需要 15 分钟并获得大约 1 GB 的 RAM,然后抛出 OutOfMemoryException - 我认为 Entity Framework 正在将所有记录作为对象加载到内存中 - 但为什么呢?另一方面,简单的 SQL 大约需要 3 秒,并且不会占用大量 RAM。
using (var db = new MyContext())
{
var res1 = from sample in db.Samples
group sample by sample.Channel into g
select new { Channel=g.Key, Events = g.Sum(s => s.Events) };
res1.ToArray();
var res2 = db.Natas.FromSql("SELECT Channel as ChannelID, Channel as Ch, SUM(Events) as Es FROM Sample GROUP BY Channel");
var data = res2.ToArray();
}
有什么建议吗?感谢您的帮助;)
【问题讨论】:
-
为什么需要'orderby'?
-
我使用 order by 以正确的顺序获得结果(也许我应该在分组后使用它) - 在这种情况下它并不重要 - 删除这部分 linq 后,性能仍然相同。我删除了问题代码中的 OrderBy 部分,以使其更清晰。
-
但 order by 不在“更快的纯 sql”中。除非 SQL 在功能上相同,否则您将苹果与橙子进行比较。
-
你检查过EF生成并发送到数据库的查询吗?
-
最新版本中 EF 的 SQLite 提供程序在显示 SQL 时出现问题;/ - 这就是我决定在这里提出这个问题的原因。
标签: c# performance entity-framework sqlite linq-to-sql