提高 SQLite 写入速度 C# [英] Improve SQLite writing speed C#

查看:38
本文介绍了提高 SQLite 写入速度 C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要显着提高 SQLite 的写入速度(或者可能为此提出 SQLite 之外的其他解决方案).

I need to dramatically improve writing speed for SQLite (or maybe suggest another solution for this outside of SQLite).

场景:

  • 我有 71 列,每列有 365 * 24 * 60 个值.(365 = 天)
  • 我会插入"用于测试 db_performance
  • 为了缩短测试时间,我进行了 90 天而不是 365 天的测试(因此结果时间跨度将为 x4)

设置:我已经尝试了各种 PRAGMAS,比如

Settings : I've tried various PRAGMAS like

  • 同步关闭
  • locking_mode 独占
  • 缓存&具有不同值的 pagesize(虽然我读取低值可能会提高性能,但对我来说更高的值做得很好)
  • journal_mode 关闭
  • 更改超时值

方法:

  • #A1 收集所有insert intos",每个 ExecuteNonquery,最后做一个巨大的交易
  • #A2 与上面相同,但使用 ParallelForEach 和 ExecuteNonqueryAsync
  • #A3 收集所有插入"一天,每人做一笔交易

表格结构:

  • #T1 一张包含所有列的表格
  • #T2 每列一张表

结果:我确实运行了 90 天(所以不会花太长时间),主要问题是写入速度.

Results : I did runs for 90 days ( so it doesn't take too long ) and the main problem is writing speed.

我测量了 5 个阶段,它们是:

I measured 5 phases, which are :

  • #P1 设置表格 &标题(~8-9ms)
  • #P2 准备数据(对于每个插入"命令执行 ExecuteNonquery)(~15000-18000 毫秒!)
  • #P3 执行事务(~ 200-500 毫秒)
  • #P4 读取一整列(~80 - 200 毫秒)
  • #P5 删除一整列(~ 1 - 9 毫秒)

我尝试了之前提到的所有不同方法和方法,但无法改进#P2.任何想法如何解决这个问题?或者,是否有更好的解决方案作为无服务器数据库(领域?)的提示?

I tried all the different methods and approaches I mentioned before, but couldn't manage to improve #P2. Any ideas how to fix that ? Or maybe any hint for a better solution as a serverless db (Realm?) ?

这里是#A1 #P2 #T2 的代码,它目前取得了最好的结果......

Here's the code for the #A1 #P2 #T2, which had the best results so far...

using (var transaction = sqLiteConnection.BeginTransaction())
{
    using (var command = sqLiteConnection.CreateCommand())
    {
        foreach (var vcommand in values_list)
        {
            command.CommandText = vcommand;
            command.ExecuteNonQuery();
        }
    }
                        
    transaction.Commit();
}

(值列表是一个字符串[],带有 71*90 插入或在 Marks 版本中是一个巨大的命令.)

(values list is a string[] with 71*90 insert intos or in Marks version one giant command.)

编辑/更新:我尝试了 Mark Benningfield 的方法,制作了一个巨大的插入"对于一个表中所有列的所有值,可以将整体速度提高到 ~8500ms (#P2 ~7500ms).

Edit/Update : I tried the approach by Mark Benningfield making one giant "insert into" for all values in one table with all columns and could improve the overall speed to ~8500ms (#P2 ~7500ms).

最终更新:好的,我做了一堆测试,并将总结结果:

Final Update : Ok I did a bunch of tests and will summarize the results :

出于比较原因,所有数据库都具有相同的值,即具有 [129600,71] 值的二维双精度数组.它们都没有准备好的插入语句,因此包括将值转换为所需格式的生成时间(第 2 阶段).

For comparison reason all databases had the same values, a two-dimensional double array with [129600,71] values. None of them had a prepared insert-statement, so the generation time for transforming the values into the needed format is included (phase 2).

SQLite 需要大约 14 秒来处理一个巨大的事务(之前的大约 8 秒没有实时生成插入命令).SQL_CE 最适合这种情况.这主要是因为不使用字符串(INSERT INTO"),而是使用数据表和行 + 批量插入.Realm 很有趣,尤其是对于移动用户来说——非常直观.但是你不能添加动态对象 atm(所以你需要一个静态对象).Influx 是另一个不错的时间序列数据库,但它非常具体,不是嵌入式的,恕我直言,C# 实现很差(它可能通过控制台执行得更好).

SQLite needs ~14seconds with one giant transaction (the previous ~8s were without generating the insert-into-command live). SQL_CE is atm the best for this scenario. This is mainly due to not operating with strings ("INSERT INTO"), but with DataTables and rows + bulkInsert. Realm is interesting, especially for mobile users - very intuitive. But you cannot add dynamic obejcts atm (so you need a static object). Influx is another nice database for timeseries, but it's very specific, not embedded and has IMHO a poor C# implementation (it may perform much better via console).

推荐答案

使您的插入命令看起来像这样(通过根据需要构造它):

Make your insert command look like this (by constructing it however you need to):

INSERT INTO table (col1, col2, col3) VALUES (val1, 'val2', val3),
    (val1, 'val2', val3),
    (val2, 'val2', val3),
    ...
    (val1, 'val2', val3);

然后执行single插入命令对已知数据进行批量更新.

Then execute the single insert command to do a bulk update of known data.

这篇关于提高 SQLite 写入速度 C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆