使用ASP.NET Core,SQlite与postgres相比非常慢

时间:2018-02-06 20:35:53

标签: asp.net performance sqlite entity-framework-core asp.net-core-2.0

在我使用实体框架核心的ASP.NET Core 2.0 RESTful API中,我有一个重复调用的函数,一次调用几个。函数本身是一个简单的更新,它将记录的值从0翻转为1并再次返回并保存更改。

在正常操作过程中,页面可能会同时进行大约10个查询。如果我使用SQlite,由于某种原因,所有查询在调用后同时返回大约1000ms(!)。

所以我尝试迁移到postgres和(令人震惊的),它可以在每个查询大约40-200毫秒内完成相同数量的工作。

AFAIK,SQlite应该更快,因为无论如何数据存储都很小(~100kb)。那么为什么这里存在如此大的差异呢?

编辑:我已经阅读this github issue,其中说所有请求都会被串行处理,因此I / O阻塞可能是游戏因素,但我真的不能看到SQlite花了这么多时间进行这么简单的操作。我正在使用的代码:

public async Task<IActionResult> mark([FromRoute] int id)
{
    Foo foo = await _context.Foo.Where(m => m.id == id)
                                .Include(m => m.RelatedTable)
                                .SingleOrDefaultAsync();

    if (foo == null) return BadRequest();
    if (foo.relatedtable.Count > 0) return BadRequest("No related records");

    foo.bar = 1;

    _context.Update(foo);

    await _context.SaveChangesAsync();

    return Content("success");
}

2 个答案:

答案 0 :(得分:1)

SQLite是一个基于文件的数据库,主要依赖于OS文件缓存。这意味着如果操作系统减少缓存,则可能会变慢,因为文件是由例如网络上的多个客户端访问的。

无论如何,提交事务时大部分时间都花在同步上。进行多项操作时,您应始终wrap them into a single transaction

答案 1 :(得分:1)

纯粹猜测,但有些事情浮现在脑海中:

  1. SQLite不支持Async,因此这些调用只会增加额外的开销。
  2. Npgsql缓存已编译/准备好的SQL语句,而Microsoft.Data.Sqlite每次都必须重新编译SQL(问题#5459会对此有所帮助)
  3. 通过在查询和更新之间保持连接打开(在查询之前调用_context.Database.OpenConnection()),您可以获得更好的吞吐量。
  4. 使用_context.Database.ExecuteSqlCommand("PRAGMA journal_mode=WAL;")
  5. 启用预写日志记录(WAL)