6

我在这里尝试实现的是一个条件,其中一个 sqlite 数据库只保存最近的 1000 条记录。我有每条记录的时间戳。立即发生的低效逻辑之一是检查记录总数。如果它们超过 1000,则只需删除掉出外围的那些。

但是,我必须对每个 INSERT 进行此检查,这会使事情变得非常低效。

有什么更好的逻辑?我们可以用触发器做点什么吗?

一些遵循我想到的相同逻辑的相关问题发布在SO上:-

从数据库中删除最旧的记录

SQL查询删除超过两年的记录

4

1 回答 1

10

您可以为此使用隐式“rowid”列。

假设您不以不同方式手动删除行:

DELETE FROM yourtable WHERE rowid < (last_row_id - 1000)

您可以使用API 函数或 as获取最后一个 rowidmax(rowid)

如果您不需要恰好有1000 条记录(例如,只想清理旧记录),则不必在每次插入时都这样做。在您的程序中添加一些计数器并每 100 次插入执行一次 cleanup fi。

更新:

无论如何,您要为每次插入或每次选择支付性能。所以选择取决于你有更多:INSERTs 或 SELECTs。

如果您没有那么多插入来关心性能,您可以使用以下触发器来保留不超过 1000 条记录:

CREATE TRIGGER triggername AFTER INSERT ON tablename BEGIN
     DELETE FROM tablename WHERE timestamp < (SELECT MIN(timestamp) FROM tablename ORDER BY timestamp DESC LIMIT 1000);
END

在时间戳列上创建唯一索引也应该是一个好主意(以防它已经不是 PK)。另请注意,SQLITE 仅支持FOR EACH ROW触发器,因此当您批量插入许多记录时,暂时禁用触发器是值得的。

如果 INSERT 太多,您在数据库方面无能为力。您可以通过添加触发条件(如AFTER INSERT WHEN NEW.rowid % 100 = 0. 并且选择只需使用 LIMIT 1000 (或创建适当的视图)。

我无法预测那会快多少。最好的方法是衡量在特定情况下您将获得多少性能。

于 2013-09-07T20:44:44.433 回答