如何更快地在SQLite中列出主键列?

时间:2019-01-15 17:06:03

标签: c# sql sqlite

我有一个.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;

2 个答案:

答案 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中的实际表名。

另请参见
SQLite Connection Strings

答案 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),如果需要,至少要定期对其进行碎片整理。