【问题标题】:Bulk DB Operation Strategy批量数据库操作策略
【发布时间】:2014-01-02 14:52:34
【问题描述】:

我在一个 Android 应用程序中运行了一个 SQLite 数据库,它在一个月内分批传输用户数据。

应用程序首次运行时,尚未下载任何数据,使用 INSERTS 进行存储是一件小事。

但是,当用户重新下载一个月的数据时(从主数据库获取任何潜在的更新(我想推送小的、一条记录更新,但这是 2.0 的功能))我需要找到一个高效的存储记录的方式。

目前,我使用蛮力并简单地删除正在刷新的月份的所有记录,然后是 INSERTS。我不想拥有一大堆逻辑和数据库访问,或存储元数据,以跟踪哪些记录是新的,哪些是现有的,然后相应地执行插入和更新。

我的老板说 DELETE 可能是一项昂贵的操作,这是真的吗?我是否应该输入一些逻辑来确定应该更新哪些记录以及应该插入哪些记录,而不是 DELETING 然后 INSERTING ?此策略还需要确定在主数据库端也删除了哪些记录(我选择退出的另一个原因)。

如果有一种完全更好/有效的方法可以做到这一点,我还没有提到,请告诉我。谢谢。

【问题讨论】:

  • Delete+Insert 是两个数据库操作,而不是一个更新操作。如果涉及索引,成本可能会更高。问题是,您使用了多少数据?我会先用删除+插入进行音量测试。如果性能是可以接受的,您可能会争辩说,采用更复杂的策略是不值得的......
  • 大约 1 MB,对于较小的城市来说,大约要少一些,而对于较大的城市来说可能要大得多。我们会,因为大多数操作都是更新,还有另一个原因要添加逻辑,虽然我真的不想这样做,因为时间是一个主要因素。

标签: android sql sqlite bulkinsert


【解决方案1】:

我的老板说 DELETE 可能是一项昂贵的操作,这是真的吗?

这取决于一个人对“昂贵”的定义。我不知道对于相同的受影响记录,DELETEUPDATE 贵得多(事实上,它可能更便宜)。

我应该输入一些逻辑来确定应该更新哪些记录以及应该插入哪些记录,而不是删除然后插入?

我们没有很好的方法来回答这个问题,因为它在很大程度上取决于您的环境,例如您的数据库架构。

确保将这些操作包装在事务中,因为这会对批量操作的速度产生重大影响。

除此之外,您还需要运行一些自己的性能基准测试,以确定DELETE+INSERTUPDATE 贵多少,因此是否值得开发头痛尝试切换到以UPDATE 为中心的策略。

【讨论】:

  • 我确实在需要独占写入权限的其他地方使用事务(当后台进程更新排队的记录而没有数据库连接时,并且用户可能打开了记录,以及许多其他乐趣情景)。我正在处理的这个领域需要进行重大优化,b/c 目前,对于每个记录和子记录,执行单独的 DB 操作,包括打开和关闭 DB 连接。这就是它的进展方式,但人是缓慢的。无论我选择什么路线,我肯定会以批量操作的形式进行(构建一个或几个错误命令字符串)。谢谢
  • 我认为 SQLite 将所有命令隐式包装在事务中?所以,如果我确实执行了一个包含数百或数千个插入的单个批量(如在大量字符串中)命令,它不是已经在事务中了吗?你如何定义bulk,b/c 我觉得我的想法和你的不一样?
  • @SamusArin:“如果我确实执行了包含数百或数千个插入的单个批量(如在大量字符串中)命令,它不是已经在事务中了吗?” ——我从未尝试过。我希望它是“成百上千”的交易。更不用说构建一个代表“成百上千”插入的单个 SQL 字符串会极大地浪费 RAM。请使用 beginTransaction() 和 kin 将单个 execSQL() 调用包装到事务中。
  • 哦,伙计,如果您告诉我我需要做的就是将所有内容包装在我将要设置的事务中!我会试一试。也非常感谢您清理一切。
  • 成功了!我只剃了 1 分钟到 10 秒!!!我的存储库已经设置为执行事务,在这种情况下我只是没有使用它们。非常感谢,我很高兴我能够利用我现有的代码,而不必编写一个全新的数据访问层来构建一个巨大的命令字符串!
猜你喜欢
  • 2010-09-24
  • 1970-01-01
  • 2020-06-19
  • 2017-06-11
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
相关资源
最近更新 更多