Медленная пакетная / массовая вставка в SQLite - PullRequest
4 голосов
/ 10 марта 2011

Я пытаюсь импортировать данные из CSV-файла в таблицу sqlite.Мои тестовые данные составляют всего около 8 МБ (50000 строк) и занимают около 15 секунд.Однако производственные данные составляют почти 400 МБ и занимают вечность (как минимум 30 минут +, я перестал ждать).

После долгих исследований я обнаружил необходимость выполнения вставок в одной транзакции (что привело меня кВторой импорт, отличный совет! :)) Так что это не проблема.(AFAIK)

Я также использую «ExecuteNonQuery () для параметризованного оператора INSERT» согласно этому сообщению Роберта Симпсона - и многочисленным вариантам.

Я был простоиспользуя TextReader.ReadLine() и String.Split('\t'), я где-то читал о том, что ReadLine() медленный из-за количества операций чтения с диска, поэтому я посмотрел на чтение bufferedStream и наткнулся на этот csv reader .Но все еще нет заметного изменения в производительности.

Итак, я закомментировал кишки моего цикла вставки, и чтение произошло почти мгновенно - так что я уверен, что проблема заключается в моей вставке.Я пробовал множество вариантов создания параметризованных запросов + одной транзакции, но все с почти одинаковыми результатами.

Вот обычная версия моего кода.Заранее спасибо, это сводит меня с ума!Я собираюсь попробовать импортировать в набор данных и вставить это? ....

using (TextReader tr = File.OpenText(cFile))
{                       
    using (SQLiteConnection cnn = new SQLiteConnection(connectionString))
    {
        string line;
        string insertCommand = "INSERT INTO ImportTable VALUES (@P0,@P1,@P2,@P3,@P4)";

        cnn.Open();
        SQLiteCommand cmd = new SQLiteCommand("begin", cnn);
        cmd.ExecuteNonQuery();

        cmd.CommandText = insertCommand;

        while ((line = tr.ReadLine()) != null)
        {
            string[] items = line.Split('\t');

            cmd.Parameters.AddWithValue("@P0", items[0]);
            cmd.Parameters.AddWithValue("@P1", items[1]);
            cmd.Parameters.AddWithValue("@P2", items[2]);
            cmd.Parameters.AddWithValue("@P3", items[3]);
            cmd.Parameters.AddWithValue("@P4", items[4]);
            cmd.ExecuteNonQuery();
        }
        cmd.CommandText = "end";
        cmd.ExecuteNonQuery(); 
    }              
}

Обновление: я только что попытался использовать вставку с параметрами (просто жестко запрограммированные некоторые значения), менее 5 секунд... все еще не так быстро, как статьи, которые я видел ...

Кроме того, я использую Core2 Duo (3Ghz) с 2G Ram, XP.

1 Ответ

1 голос
/ 12 марта 2011

Так что я думаю, что я решил проблему - или, по крайней мере, нашел решение.

Поскольку я исчерпал все свои параметры кода (и, похоже, никто не имел ответа / проблемы с моим кодом), я решил, что проблема может заключаться в самой базе данных ...

Я создал свою базу данных и все таблицы в плагине SQLite Manager Firefox.

Итак, я воссоздал все из командной оболочки и BOOM! Мой импорт упал до нескольких секунд!

Я знал, что проблема в том, что он не может обрабатывать 64-битные целые числа (но только использовал типы данных TEXT). Возможно, есть проблема с SQLite Manager, использующим движок SQLite, отличный от версии .Net? Я не знаю.

Моим следующим шагом может быть создание таблиц db + из моего приложения вместо их предварительной подготовки ... Но сейчас я вполне доволен производительностью, так что это не является приоритетом.

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