Как вывести список столбцов первичного ключа в SQLite быстрее? - PullRequest
0 голосов
/ 15 января 2019

У меня есть база данных .sqlite, которая содержит 4 500 000 маленьких изображений (всего 24 ГБ) и имеет два столбца. Вот код создания таблицы:

CREATE TABLE `OldImages` (
`Id`    INTEGER NOT NULL,
`Image`    BLOB NOT NULL,
CONSTRAINT `PK_Images` PRIMARY KEY(`Id`)
);

Я решил загрузить список идентификаторов в HashSet<long> для более быстрого контроля времени выполнения того, что уже находится в базе данных, и потребовалось 10 часов 100% активности диска для завершения. Есть ли лучший способ сделать это? Помимо хранения списка в другом месте в простом двоичном файле - который я, вероятно, в конечном итоге буду делать, поскольку он составляет 36 МБ и загружается мгновенно.

Вот код 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 голосов
/ 16 января 2019

Хорошо, я должен был попробовать дефрагментацию и HDD против SSD, прежде чем задавать вопрос о моем коде. В этих тестах используется Dapper (как предложено в ответе Роберта Харви), но это само по себе не меняет скорости.

150 МБ базы данных, 2 000 000 строк, ~ 136 МБ ОЗУ:

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

4 500 000 строк, ~ 300 МБ ОЗУ:

HDD = 28min
HDD (defrag) = 13min
SSD = 28s (with both Dapper and my original code)

Каждому тесту предшествовала перезагрузка системы для предотвращения кэширования.

Так что, я думаю, довольно очевидный ответ: Не используйте жесткие диски (по крайней мере, 4 ТБ WD Blue) для баз данных SQLite, и, если необходимо, по крайней мере, регулярно их дефрагментируйте.

0 голосов
/ 15 января 2019

Вместо того, чтобы пытаться понять, почему SQLiteDataReader такой медленный, давайте просто обойдем его и используем более эффективную технику исполнения.

Сначала добавьте Dapper в ваш проект. Вы можете получить его от здесь .

Затем добавьте в начало своего класса:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...