我有一个.sqlite数据库,其中包含4 500 000个小图像(共24 GB),并有两列。这是表创建代码:
CREATE TABLE `OldImages` (
`Id` INTEGER NOT NULL,
`Image` BLOB NOT NULL,
CONSTRAINT `PK_Images` PRIMARY KEY(`Id`)
);
我决定将Ids列表加载到HashSet<long>
中,以便对数据库中已有的内容进行更快的运行时控制,并且完成了100%的磁盘活动需要10个小时。有没有更好的办法来解决这种事情?除了将列表保存在简单的二进制文件中之外-从现在起我可能最终会做,因为它有36MB的内存并可以立即加载。
这是C#代码:
var results = new HashSet<long>();
using (var cmd = new SQLiteCommand (Program.DbImages))
using ( var transaction = Program.DbImages.BeginTransaction())
{
SQLiteDataReader reader;
cmd.CommandText = $"Select Id FROM {table}" ;
reader = cmd.ExecuteReader();
while (reader.Read())
{
var result = reader.GetInt64(0);
results.Add((result));
}
transaction.Commit();
}
return results;
答案 0 :(得分:0)
与其试图找出为什么SQLiteDataReader
这么慢的原因,不如让我们绕开它并使用一种性能更好的技术。
首先,将Dapper添加到您的项目中。您可以从here获得它。
然后,添加到课程的顶部:
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using Dapper;
我不确定您如何与当前的SQL数据提供程序建立连接,但是您需要使用连接字符串来与Dapper进行连接。
var connection = new SqlConnection(myConnectionString);
然后执行以下代码:
var data = connection.Query<long>("SELECT Id FROM {table}");
var hashSet = new HashSet<long>(data);
请确保将{table}
替换为SQLite中的实际表名。
答案 1 :(得分:0)
好吧,在质疑我的代码之前,我应该先尝试进行碎片整理和HDD vs. SSD。这些测试使用的是Dapper(罗伯特·哈维(Robert Harvey)的回答中提出了这一点),但是它本身并没有造成速度差异。
150MB数据库,2000000行,〜136 MB RAM:
y
450万行,〜300 MB RAM:
A 2018 4TB WD Blue HDD = 6m 31s
same HDD after defragmenting the database file = 2m 32s
an old SATA Corsair Force3 120GB SSD = 8s
在每次测试之前,系统都会重新启动以防止缓存。
所以我想答案很明显是: 不要对SQLite数据库使用HDD(至少不要使用4TB WD Blue),如果需要,至少要定期对其进行碎片整理。