Как я могу утилизировать SqliteCommand для ускорения этой массовой вставки Sqlite (iOS)? - PullRequest
9 голосов
/ 15 марта 2011

Я использую приведенный ниже код для массовой вставки 30000 строк (1000 строк за раз). Тем не менее, это не так быстро, как могло бы быть. В этом примере Улучшить производительность SQLite по INSERT-в-секунду? Я вижу, что они создают SqliteCommand только один раз, а затем повторно выполняют его, сбрасывая и удаляя привязки. Однако я не могу найти подходящие методы на iOS / Monotouch. Там нет Reset() или ClearBindings() или что-либо еще похожее.

using ( var oConn = new SqliteConnection ( "Data Source=" + DB_NAME ) )
{
    oConn.Open (  );

    // Wrap the whole bulk insertion into one block to make it faster, otherwise one transaction per INSERT would be created.
    // Note that this is differen from "BEGIN TRANSACTION" which would increase memory usage a lot!
    SqliteCommand oCmd = new SqliteCommand ( "BEGIN", oConn );
    oCmd.ExecuteNonQuery (  );
    oCmd.Dispose (  );

    foreach ( MyObj oObj in aMyObjects )
    {
        oCmd = new SqliteCommand ( "INSERT INTO LocalObjects ( intID, intParentID, intObjectType, strName, dtModified VALUES (@intID, @intParentID, @intObjectType, @strName, @dtModified)", oConn );
        oCmd.Parameters.AddWithValue ( "@intID", oMyObj.ID );
        oCmd.Parameters.AddWithValue ( "@intParentID", oMyObj.ParentID );
        oCmd.Parameters.AddWithValue ( "@intObjectType", ( int ) oMyObj.Type );
        oCmd.Parameters.AddWithValue ( "@strName", oMyObj.Name );
        oCmd.Parameters.AddWithValue ( "@dtModified", oMyObj.Modified );
        oCmd.ExecuteNonQuery (  );
        oCmd.Dispose (  );
    }

    oCmd = new SqliteCommand ( "END", oConn );
    oCmd.ExecuteNonQuery (  );
    oCmd.Dispose (  );

    oConn.Close (  );
    oConn.Dispose (  );
}

Ответы [ 2 ]

11 голосов
/ 15 марта 2011

Попробуйте изменить свой код следующим образом:

using ( var oConn = new SqliteConnection ( "Data Source=" + DB_NAME ) )
{
    oConn.Open (  );

    // Wrap the whole bulk insertion into one block to make it faster, otherwise one transaction per INSERT would be created.
    // Note that this is differen from "BEGIN TRANSACTION" which would increase memory usage a lot!
    SqliteCommand oCmd = new SqliteCommand ( "BEGIN", oConn );
    oCmd.ExecuteNonQuery (  );
    oCmd.Dispose (  );

    oCmd = new SqliteCommand ( "INSERT INTO LocalObjects ( intID, intParentID, intObjectType, strName, dtModified VALUES (@intID, @intParentID, @intObjectType, @strName, @dtModified)", oConn );

    // <do this for all of your parameters>.
    var id = oCmd.CreateParameter();
    id.ParameterName = "@intID";
    oCmd.Parameters.Add(id);
    // </do this for all of your parameters>.

    foreach ( MyObj oObj in aMyObjects )
    {
        // <do this for all of your parameters>.
        id.Value = oMyObj.ID;
        // </do this for all of your parameters>.

        oCmd.ExecuteNonQuery (  );
    }

    oCmd.Dispose();

    oCmd = new SqliteCommand ( "END", oConn );
    oCmd.ExecuteNonQuery (  );
    oCmd.Dispose (  );

    oConn.Close (  );
    oConn.Dispose (  );
}

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

0 голосов
/ 15 марта 2011

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

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