我在这里尝试实现的是一个条件,其中sqlite数据库仅包含最近的1000条记录。我有每条记录的时间戳。 立即攻击的低效逻辑之一是检查记录总数。如果它们超过1000,那么只需删除掉外围的那些。
但是,我必须对每个INSERT进行检查,这会使效率非常低。
什么是更好的逻辑?我们可以用触发器做点什么吗?
遵循我想到的相同逻辑的一些相关问题发布在SO: -
答案 0 :(得分:8)
您可以使用隐式"rowid"列。
假设您不以不同方式手动删除行:
DELETE FROM yourtable WHERE rowid < (last_row_id - 1000)
您可以使用API function或max(rowid)
如果您不需要完全 1000条记录(例如只想清理旧记录),则不必在每个插入上执行此操作。在程序中添加一些计数器并执行清理f.i.每100次插入一次。
无论如何,您需要在每个插入或每个选择上支付性能。所以选择取决于你有更多: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
在timestamp列上创建唯一索引也应该是一个好主意(如果它已经不是PK)。另请注意,SQLITE仅支持FOR EACH ROW
个触发器,因此当您批量插入许多记录时,暂时禁用触发器是值得的。
如果INSERT太多,那么在数据库方面你无能为力。通过添加AFTER INSERT WHEN NEW.rowid % 100 = 0
等触发条件,您可以实现频率较低的触发器调用。选择只需使用LIMIT 1000(或创建适当的视图)。
我无法预测会有多快。最好的方法是衡量你在特定情况下会获得多少性能。