我有一个RecyclerView项目列表,它使用SQLite数据库来存储用户输入数据。我使用传统的_id列作为INTEGER PRIMARY KEY AUTOINCREMENT。如果我理解正确,数据库中新插入的行将添加到现有行下方,新的ROWID将获取最大的现有ROWID并将其递增+1。因此,对最新插入的光标搜索必须扫描整个行集以到达数据库的底部。例如,在10次插入之后,光标必须从1,2,3 ......向下搜索,直到它到达第10行。
为了避免冗长搜索整个ROWID集,有没有办法将新插入添加到数据库的顶部而不是底部?这样,使用moveToFirst()的光标搜索最新插入将非常快,因为光标将在它搜索的第一行(数据库的顶部)停止。光标将搜索10,9,8,... 3,2,1,因此搜索速度非常快,因为它将停在10,即数据库顶部的第一行。
答案 0 :(得分:2)
您对数据库内部的思考太多了。索引是为这种优化而设计的。
创建一个新的数字列,将您希望的排序作为值,并在选择中使用order by
。不要忘记在此列上创建索引并验证您的选择是否使用索引。 (explain
)
答案 1 :(得分:0)
首先,如果您担心间接费用,请使用推荐的INTEGER PRIMARY KEY
而不是INTEGER PRIMARY KEY AUTOINCREMENT
。两者都会产生一个唯一的id,后者的开销按照: -
AUTOINCREMENT关键字会占用额外的CPU,内存,磁盘空间和 磁盘I / O开销,如果不是严格需要,应该避免。它是 通常不需要。 SQLite Autoincrement
如果我理解正确,数据库中新插入的行是 添加到现有行下面,新的ROWID占用最大的行 ROWID并将其递增+1。
通常但不一定,不能保证该值会增加1.
AUTOINCREMENT使用一个名为sqlite_seqeunce的表,每个表都有一行,用于存储最后一次使用的最大序列号以及表名。下一个序列号将是该值+可能为1,除非最高rowid大于sqlite_sequence表中的值。
如果没有AUTOINCREMENT,则下一个序列是最高的rowid +可能是1。
AUTOINCREMENT保证更高的数字。没有AUOINCREMENT可以使用较低的数字(但不要直到数字大于9223372036854775807)。如果AUTOINCREMENT使用的数字高于此值,则会发生SQLITE_FULL异常。
再次关于rowid和搜索: -
rowid表的数据存储为包含的B-Tree结构 每个表行的一个条目,使用rowid值作为键。这个 意味着通过rowid检索或排序记录很快。搜索 对于具有特定rowid的记录,或对于具有rowid的所有记录 在指定范围内的速度大约是类似搜索速度的两倍 通过指定任何其他PRIMARY KEY或索引值来完成。 ROWIDs and the INTEGER PRIMARY KEY
为避免长时间搜索整套ROWID,有没有 将新插入的方法添加到数据库的顶部而不是 底部?
是的,只需在插入时指定rowid的值或通常指定别名(但要注意使用已使用的值并且好好管理编号)。但是,我怀疑这样做会导致更快的搜索。默认情况下,表具有rowid主要是因为rowid被优化以便通过rowid进行搜索。