【问题标题】:ServiceStack.Ormlite for sqlite with really slow running timeServiceStack.Ormlite 用于运行时间非常慢的 sqlite
【发布时间】:2016-08-03 17:53:11
【问题描述】:

我在 Windows 7 上使用 ServerStack.OrmLite 4.0。 我用 OrmLite 创建了一个表,并在 Sqlite 文件中插入了大约 100 行数据。 Db.Select() 的时间大约需要 1 分钟。当我将数据库更改为 mysql 时,它会立即返回结果。我还尝试使用另一个 GUI 软件访问 sqlite 数据库,并尝试执行一些 sql 语句,它们都运行良好。有人知道吗?

更新代码:

static void Main(string[] args)
    {
        string dbName = "testdb.sqlite";
        var path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        if (!System.IO.File.Exists(path + "/" + dbName))
        { 
            System.IO.File.Create(path + "/" + dbName).Dispose();
        }
        var dbFacory = new OrmLiteConnectionFactory("Data Source=./testdb.sqlite;Version=3;UTF8Encoding=True;", SqliteDialect.Provider);
        //var dbFacory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider);
        var db = dbFacory.OpenDbConnection();
        db.DropAndCreateTable<TestTable>();
        db.DropAndCreateTable<BasicPersonnelInfo>();

        Console.WriteLine("Starts at : {0}", DateTime.Now.Second);
        for (int i = 0; i < 100; i++)
        {
            db.Insert<TestTable>(new TestTable { TestField = i.ToString()});
            db.Insert<BasicPersonnelInfo>(new BasicPersonnelInfo { Test3 = i.ToString()});
        }
        Console.WriteLine("Inserting Completed;");
        Console.WriteLine("Select at : {0}", DateTime.Now.Second);
        db.Select<BasicPersonnelInfo>();
        Console.WriteLine("Ends   at : {0}", DateTime.Now.Second);
        Console.WriteLine("Prese anykey to quit!");
        Console.ReadKey();
    }

【问题讨论】:

    标签: c# sqlite servicestack


    【解决方案1】:

    如果您将 SQLite 保存到磁盘,由于文件权限,我已经看到运行时间非常长,如果您在 ASP.NET 中运行,您的 SQLite 数据库应该保存在您的 ~/App_Data 文件夹中,并且应该给出对IIS_USR 用户帐户的写入权限。

    为了提供一些关于预期所需时间的想法,我添加了一个Simple Insert/Select Benchmark,它在包含内存中两个 SQLite 的 20 个字符串列的表中插入和选择 100 行:

    var dbFactory = new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider);
    using (var db = dbFactory.Open())
    {
        db.DropAndCreateTable<TableWithStrings>();
    
        var sw = Stopwatch.StartNew();
        for (int i = 0; i < 100; i++)
        {
            var row = TableWithStrings.Create(i);
            db.Insert(row);
        }
        "[:memory:] Time to INSERT 100 rows: {0}ms".Print(sw.ElapsedMilliseconds);
    
        sw = Stopwatch.StartNew();
        var rows = db.Select<TableWithStrings>();
        "[:memory:] Time to SELECT {0} rows: {1}ms".Print(rows.Count, sw.ElapsedMilliseconds);
    }
    

    还有一个 SQLite 文件数据库:

    var dbPath = "~/App_Data/db.sqlite".MapProjectPath();
    var dbFactory = new OrmLiteConnectionFactory(dbPath, SqliteDialect.Provider);
    using (var db = dbFactory.Open())
    {
        db.DropAndCreateTable<TableWithStrings>();
    
        var sw = Stopwatch.StartNew();
        for (int i = 0; i < 100; i++)
        {
            var row = TableWithStrings.Create(i);
            db.Insert(row);
        }
        "[db.sqlite] Time to INSERT 100 rows: {0}ms".Print(sw.ElapsedMilliseconds);
    
        sw = Stopwatch.StartNew();
        var rows = db.Select<TableWithStrings>();
        "[db.sqlite] Time to SELECT {0} rows: {1}ms".Print(rows.Count, sw.ElapsedMilliseconds);
    }
    

    在我的 2013 Macbook Pro 工作站(有 4 个 VS 实例和多个 RDBMS 在后台运行)上将其作为 VS.NET 2015 中的 R# NUnit 测试运行,结果:

    [:memory:] Time to INSERT 100 rows: 10ms
    [:memory:] Time to SELECT 100 rows: 1ms
    

    对于 SQLite 文件数据库:

    [db.sqlite] Time to INSERT 100 rows: 659ms
    [db.sqlite] Time to SELECT 100 rows: 13ms
    

    虽然这不是一个适当的基准(即没有预热,不在控制台应用程序中进行更多迭代),但它应该提供一些关于预期结果的指示。注意 OrmLite 测试使用 ServiceStack.OrmLite.Sqlite.Mono 版本的 OrmLite SQLite。

    【讨论】:

    • 我正在将 SQLite 保存到磁盘。谢谢,我试过在内存中使用 SQLite 数据库。它仍然很慢(它所花费的时间与我从内存中的 SQLite 数据库中选择所花费的时间大致相同),因此文件权限被排除在外。我不知道发生了什么。
    • @gnaix 绝对不应该在 1 分钟内使用 SQLite 在内存中插入 100 行,如果您可以创建该问题的独立重现并将其发布到我可以接受的 github 存储库看看。
    • Process Monitor 可以帮助你。
    • @mythz 谢谢。我创建了一个独立项目并尝试在内存和磁盘数据库中使用。内存中的插入语句在 1 秒内执行。磁盘数据库的插入语句执行了大约 15 秒。两个数据库的选择 100 行语句执行了大约 5 秒。我有大约 20 列字符串,但这应该发生吗?
    • @mythz 好吧,你不会相信的......但是在我切换到 Mono SQLite 版本之后......它工作得很好。即使为什么对我来说仍然是一个神话......我现在要接受你的回答。我标记了这个神话,并会在其他时候研究它....
    猜你喜欢
    • 2013-01-30
    • 1970-01-01
    • 2012-12-18
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    相关资源
    最近更新 更多