Почему вставка SQLite может быть очень медленной?(Используемые транзакции) - PullRequest
1 голос
/ 01 декабря 2011

Я вставляю 8500 строк в базу данных SQLite.Требуется > 30sec в Core 2 Duo.Он использует 70% ЦП в течение этого времени, тогда проблема заключается в использовании ЦП.

Я использую транзакцию.

Я создаю базу данных, таблицы и вставки на лету во временном файле,Тогда мне не нужно беспокоиться о коррупции и т. Д.

Я просто пытался использовать это, но не помогло:

PRAGMA journal_mode = OFF;
PRAGMA synchronous = OFF;

Что еще я могу сделать?

Если я запускаю тот же скрипт в плагине Firefox SQLite Manager, он запускается мгновенно.

Я запускаю профилировщик.

Все время на

27seg System.Data.SQLite.SQLite3.Prepare(SQLiteConnection, String, SQLiteStatement, UInt32, String&)

Этот методвызывает три метода

12seg System.Data.SQLite.SQLiteConvert.UTF8ToString(IntPtr, Int32)
9seg System.Data.SQLite.SQLiteConvert.ToUTF8(String)
4seg System.Data.SQLite.UnsafeNativeMethods.sqlite3_prepare_interop(IntPtr, IntPtr, Int32, IntPtr&, IntPtr&, Int32&)

Вы просили показать вставку.Здесь:

INSERT INTO [Criterio] ([cd1],[cd2],[cd3],[dc4],[dc5],[dt6],[dc7],[dt8],[dt9],[dt10],[dt11])VALUES('FFFFFFFF-FFFF-FFFF-FFFF-B897A4DE6949',10,20,'',NULL,NULL,'',NULL,julianday('2011-11-25 17:00:00'),NULL,NULL);

Таблица:

CREATE TABLE Criterio (
   cd1          integer NOT NULL,
   cd2         text NOT NULL,
   dc3        text NOT NULL,
   cd4    integer NOT NULL,
   dt5           DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,
   dt6         DATE NULL,
   dt7          DATE NULL,
   dc8   TEXT NULL,
   dt9   datetime NULL,
   dc10            TEXT NULL,
   dt11            datetime NULL,
   PRIMARY KEY (cd2 ASC, cd1 ASC)

);

C # Код:

        scriptSql = System.IO.File.ReadAllText(@"C:\Users\Me\Desktop\ScriptToTest.txt");

        using (DbCommand comando = Banco.GetSqlStringCommand(scriptSql))
        {
            try
            {
                using (TransactionScope transacao = new TransactionScope())
                {
                    Banco.ExecuteNonQuery(comando);
                    transacao.Complete();
                }
            }
            catch (Exception ex)
            {
                Logging.ErroBanco(comando, ex);
                throw;
            }
        }

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

Я не знаю, почему pst удалил его ответ, поэтому я буду публиковать ту же информацию из него, так как это правильный ответ.

Согласно FAQ по SQLite - INSERTдействительно медленный - я могу делать только несколько десятков INSERT в секунду

На самом деле, SQLite с легкостью будет выполнять 50 000 или более операторов INSERT в секунду на обычном настольном компьютере.Но он будет выполнять всего несколько десятков транзакций в секунду

...

По умолчанию каждый оператор INSERT является собственной транзакцией.Но если вы окружите несколько операторов INSERT с помощью BEGIN ... COMMIT, тогда все вставки будут сгруппированы в одну транзакцию.

Таким образом, в основном вам нужно сгруппировать свои INSERT по меньшему количеству транзакций.

Обновление: Таким образом, проблема, вероятно, в основном из-за огромного размера сценария SQL- SQLite необходимо проанализировать весь сценарий, прежде чем он сможет выполняться, но синтаксический анализатор будет предназначен для анализа небольших, а не массовых сценариев!Вот почему вы наблюдаете так много времени, потраченного на метод SQLite3.Prepare.

Вместо этого вам следует использовать параметризованный запрос и вставлять записи в цикл в коде C #, например, если ваши данные были в формате CSVв вашем текстовом файле вы можете использовать что-то вроде этого:

using (TransactionScope txn = new TransactionScope())
{
    using (DbCommand cmd = Banco.GetSqlStringCommand(sql))
    {
        string line = null;
        while ((line = reader.ReadLine()) != null)
        {
            // Set the parameters for the command at this point based on the current line
            Banco.ExecuteNonQuery(cmd);
            txn.Complete();
        }
    }
}
0 голосов
/ 01 декабря 2011

Вы пробовали параметризованную вставку? По моему опыту, транзакции немного улучшат скорость, но параметризованные запросы имеют гораздо большее влияние.

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