如何使用swift在iOS中将批量数据插入到SQLite数据库中

时间:2015-06-19 10:25:29

标签: ios json sqlite swift bulkinsert

我想使用Swift向本地数据库SQLite插入超过20000条记录。我从json服务获取数据。我能够成功插入记录,但是插入需要5分钟以上。我已经搜索了很多实现了开始和提交事务,但我没有发现任何执行时间的变化。以下是代码:

func saveTeamDepartmentValueData(teamDepartmentValueArray : NSMutableArray) {
    var insertTeamDepartmentValueDataQuery : String = String()

    if (teamDepartmentValueArray.count > 0) {
        var errMsg:UnsafeMutablePointer<Int8> = nil
        sqlite3_exec(database, "BEGIN TRANSACTION", nil, nil, &errMsg)

        insertTeamDepartmentValueDataQuery = "INSERT OR IGNORE INTO store_feedback_form_kpi (team_id, department_id,value_id,ordinal,sub_category_id,team_department_value_id) VALUES (?, ?, ?, ?, ?, ?)"

        println("insertTeamDepartmentValueDataQuery is \(insertTeamDepartmentValueDataQuery)")
        var cSql = insertTeamDepartmentValueDataQuery.cStringUsingEncoding(NSUTF8StringEncoding)
        var result:CInt=0
        var statement:COpaquePointer = nil
        var path = getPath()
        var dbpath = path.cStringUsingEncoding(NSUTF8StringEncoding)
        let check = sqlite3_open(dbpath!, &database)
        var teamDepartmentValueDict : NSDictionary = NSDictionary()

        sqlite3_prepare_v2(database, cSql!, -1, &statement, nil);

        for teamDepartmentValueDict in teamDepartmentValueArray
        {
            var teamDepartmentValueData : TeamDepartmentValue = TeamDepartmentValue ()
            if var teamId = teamDepartmentValueDict.valueForKey("team_id") as? String
            {
                teamDepartmentValueData.teamId = teamId.toInt()!
            }
            else{
                teamDepartmentValueData.teamId = 0
            }
            if var departmentId = teamDepartmentValueDict.valueForKey("department_id") as? String
            {
                teamDepartmentValueData.departmentId = departmentId.toInt()!
            }
            else{
                teamDepartmentValueData.departmentId = 0
            }
            if var valueId = teamDepartmentValueDict.valueForKey("value_id") as? String
            {
                teamDepartmentValueData.valueId = valueId.toInt()!
            }
            else{
                teamDepartmentValueData.valueId = 0
            }
            if var ordinal = teamDepartmentValueDict.valueForKey("ordinal") as? String
            {
                teamDepartmentValueData.ordinal = ordinal.toInt()!
            }
            else{
                teamDepartmentValueData.ordinal = 0
            }
            if var subCategoryId = teamDepartmentValueDict.valueForKey("sub_category_id") as? String
            {
                teamDepartmentValueData.subCategoryId = subCategoryId.toInt()!
            }
            else
            {
                teamDepartmentValueData.subCategoryId = 0
            }
            if var departmentValueId = teamDepartmentValueDict.valueForKey("team_department_value_id") as? String
            {
                teamDepartmentValueData.teamDepartmentValueId = departmentValueId.toInt()!
            }
            else{
                teamDepartmentValueData.teamDepartmentValueId = 0
            }

            sqlite3_bind_int(statement, CInt(1), CInt(teamDepartmentValueData.teamId))
            sqlite3_bind_int(statement, CInt(2), CInt(teamDepartmentValueData.departmentId))
            sqlite3_bind_int(statement, CInt(3), CInt(teamDepartmentValueData.valueId))
            sqlite3_bind_int(statement, CInt(4), CInt(teamDepartmentValueData.ordinal))
            sqlite3_bind_int(statement, CInt(5), CInt(teamDepartmentValueData.subCategoryId))
            sqlite3_bind_int(statement, CInt(6), CInt(teamDepartmentValueData.teamDepartmentValueId))

            result = sqlite3_step(statement)

            if(result != SQLITE_DONE)
            {
                println("failed to insert")
            }
            else
            {
                println("inserted")
            }
            sqlite3_clear_bindings(statement);
            sqlite3_reset(statement);
        }
        sqlite3_exec(database, "COMMIT TRANSACTION", nil, nil, &errMsg)
        sqlite3_exec(database, "END TRANSACTION",  nil, nil, &errMsg)
        sqlite3_finalize(statement)
        sqlite3_close(statement)
    }
}

请帮我解决这个问题。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

这可能不是问题的准确答案。

由于您要插入约20000条记录,因此需要很长时间。我想到的可以减少时间的一件事是使用GCD中的dispatch_apply方法。您可以查看this链接的Performing Loop Iterations Concurrently部分。

通过它,您将能够在并发队列上并发执行多个循环。这可能会缩短您的执行时间。我不确定它会有多快,但你可以试一试。

另外,请确保不要在单独的任务块上执行每个循环,而是将它们放入相当大的块中,以避免在安排这些任务时产生不必要的开销。