【问题标题】:Takes about 60 - 70 seconds to insert around 10000 data. Do I need to commit transactions?插入大约 10000 个数据大约需要 60 - 70 秒。我需要提交交易吗?
【发布时间】:2018-10-03 01:36:54
【问题描述】:

我正在尝试向我的数据库中插入大约 10000 个数据。检查以下函数的代码。插入所有数据大约需要一分钟。现在我已经在事务中添加了块,但我需要提交它还是自动管理。下面的代码怎么写?

func insertDataToDB(objects: [DataModel]) {
        removeAllData()
        createSchemaForData()
        print("Start Inserting Connectors \(Date())")
        let stmt = try? db.prepare("INSERT INTO product (connectorId, deviceId, current, status, cost, voltage, power, type, method, mode) VALUES (?,?,?,?,?,?,?,?,?,?)")
        do {
            try db.transaction {
                for product in objects {
                    try stmt?.run(product.connectorId!, product.deviceId!, product.current, product.status, product.cost, product.voltage, product.power, product.type!, product.method!, product.mode)
                }
            }
        } catch {
            print("Failed Inserting connectors: \(error.localizedDescription)")
        }
        print("End Inserting Connectors \(Date())")
    }

removeAllData() 在插入之前会从 db 中删除所有数据。

createSchemaForData() 将根据需要创建架构。

struct product {
    static let table = Table("product")
    static let connectorId = Expression<String>("connectorId")
    static let deviceId = Expression<String>("deviceId")
    static let current = Expression<Double?>("current")
    static let status = Expression<String?>("status")
    static let cost = Expression<Double?>("cost")
    static let voltage = Expression<Double?>("voltage")
    static let power = Expression<Double?>("power")
    static let type = Expression<String?>("type")
    static let method = Expression<String?>("method")
    static let mode = Expression<String?>("mode")
}

【问题讨论】:

  • 您可以在数据插入开始前使用begin transaction,在数据插入完成后使用commit transaction参考链接stackoverflow.com/questions/14631477/…
  • 所有这些字段都是简单的文本/数字字段吗?还是一个或多个大型 BLOB 字段?我问,因为 SQLite 中的大对象可以让它屈服。仅供参考,我确认 db.transaction 完成了必要的 BEGIN TRANSACTION/COMMIT 工作(插入 100,000 条记录需要 0.5 秒 db.transaction 和 123 秒不),所以我不认为常规的“使用事务”观察是在这里相关。还有其他事情正在发生。但是我无法根据您问题中的代码重现问题,所以您必须给我们MCVE
  • 好的@Rob,一旦我创建了一个示例项目并尝试执行类似的流程,我会告诉你的。

标签: ios swift sqlite sqlite.swift


【解决方案1】:

上面的代码没有问题,但我做错的是我创建的单例类。

我使用如下连接,每次访问db 对象时都会给我新的连接。

var db: Connection {
    let dbPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
    return try! Connection("\(dbPath)/\(dbName)")
}

因此,从查看 Rob 的代码的要点改进了代码。所以现在插入数据的时间甚至不到一秒。

let db: Connection = {
        let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
            ).first!
        return try! Connection("\(path)/EVDataBase.sqlite")
    }()

如果上面的代码还可以改进,请告诉我。或者,如果任何人都可以分享他们的单身人士或经理课程,那也会很有帮助。

【讨论】:

  • 声明: static let shared = Connection("\(path)/EVDataBase.sqlite")用法: Connection.shared.transaction
  • 是的,这个计算属性肯定会导致你描述的问题。用存储的属性替换它可以解决这个问题。好收获!
猜你喜欢
  • 2017-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-31
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多