【问题标题】:sqlite3 table with limited max lines (by choice) efficiencysqlite3 表,最大行数有限(通过选择)效率
【发布时间】:2012-03-06 07:45:18
【问题描述】:

我按间隔(gps 位置)存储数据,我不希望数据库膨胀,所以我定义了它可以达到的最大行数,然后每次插入时它都会删除最旧的行新的。

现在一位数据库专家查看了我的代码,他说这种方式效率不高,因为从数据库中删除一行是最耗费时间/内存/过程的操作,我应该不惜一切代价避免它。

他说我应该改为在达到 MAX 后遍历最旧的行(更新)。 (所以每次都是从上到下)

这意味着我需要保存一个单独的“标题”表以将当前指针保存到最旧的行并在每次插入时更新它(如果应用程序崩溃,我不想丢失它).. 它真的更有效率吗?还有其他更有效的方法吗?

【问题讨论】:

  • 与其在插入时删除/更新,为什么不按设定的时间间隔和/或在某些条件下运行作业以删除最旧的行?因此,如果您的任意最大值当前为 1,000,000 行,为什么不设置一个作业以在计数 >= 1,100,000 时删除最旧的 100,000 行?
  • @gangreen 这是一个比我原来的(我已经考虑过的)更好的实现,但它仍然与数据库专家所说的相矛盾,即它的删除本身效率不高 - 不是我的大量操作preform 所以在他看来,删除 100,000 个仍然更昂贵,然后保存一个指针并每次更新最旧的一个..
  • 我不确定我是否会称自己为专家,但我认为您的专家是错误的。插入不需要使用WHERE 子句来查找您需要的行,然后对其进行更新。如果您的更新不需要更新任何索引,那可能比需要它的插入便宜。如果您的应用程序收到大量新数据,我认为运行单个删除语句并附加 100,000 条记录会更便宜,如果它不经常接收数据,您可能可以通过更新每一行 - 底线,您可能应该设置性能限制,然后进行一些基准测试。

标签: android sql performance sqlite


【解决方案1】:

把你的数据库表变成一个环形缓冲区是愚蠢的。 如果你真的想使用这种方法...

  • 不要使用数据库,只使用数据文件和 IO
    • 在您的数据文件中,每条记录的大小都是固定的
      • [时间戳][纬度][经度]
      • 您可以使用字符串格式或二进制表示的数据,只要它们是固定大小的就没有关系。

---------gps.dat----------

[Ring Pointer]
[Time Stamp][Latitude][Longitude]
[Time Stamp][Latitude][Longitude]
...
[Time Stamp][Latitude][Longitude]
  • 环形指针是长整数的二进制表示
  • 首次创建文件时,您将其大小设置为 LONG_INTEGER_SIZE + (MAX_RECORDS * RECORD_SIZE) 的大小

当您要添加记录时:

  • 从文件开头读取[Ring Pointer]
  • 将 [Ring Pointer] + 1 写入文件开头(这样人们就不会感到困惑,保持 [Ring Pointer] 变量不变,只需将新值写回文件即可)
  • 转到位置 LONG_INTEGER_SIZE + (([Ring Pointer] % MAX_RECORDS) * RECORD_SIZE)
  • 在那个位置写下你的新记录

【讨论】:

  • 仍然不确定我们将采用哪种方式(我们可能希望未来的功能能够以某种方式查询表,从而使其纠缠使用 txt 文件表)但这是一个很好的方法IMO,应该是超级高效和便宜的。感谢您的详细解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2017-03-20
  • 1970-01-01
  • 1970-01-01
  • 2012-07-14
  • 2015-05-30
相关资源
最近更新 更多