提高 SQLite 写入速度 C# [英] Improve SQLite writing speed 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屋!