我在这里尝试实现的是一个条件,其中一个 sqlite 数据库只保存最近的 1000 条记录。我有每条记录的时间戳。立即发生的低效逻辑之一是检查记录总数。如果它们超过 1000,则只需删除掉出外围的那些。
但是,我必须对每个 INSERT 进行此检查,这会使事情变得非常低效。
有什么更好的逻辑?我们可以用触发器做点什么吗?
一些遵循我想到的相同逻辑的相关问题发布在SO上:-
我在这里尝试实现的是一个条件,其中一个 sqlite 数据库只保存最近的 1000 条记录。我有每条记录的时间戳。立即发生的低效逻辑之一是检查记录总数。如果它们超过 1000,则只需删除掉出外围的那些。
但是,我必须对每个 INSERT 进行此检查,这会使事情变得非常低效。
有什么更好的逻辑?我们可以用触发器做点什么吗?
一些遵循我想到的相同逻辑的相关问题发布在SO上:-
您可以为此使用隐式“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 (或创建适当的视图)。
我无法预测那会快多少。最好的方法是衡量在特定情况下您将获得多少性能。