Android SQLite游标是否将查询的所有数据加载到内存中,或者是否有某种优化策略是其实现的一部分?
SQLiteCursor
会在您浏览时用数据填充"窗口"。我的记忆是窗口大小为1MB,但我无法指出支持该记忆的特定代码。因此,对于小型查询,实际效果是,一旦开始访问行和列,SQLiteCursor
将在内存中保存整个结果集。
感谢CommonsWare关于Window
术语,所以我通过导航这些类SQLiteCursor -> AbstractWindowedCursor -> CursorWindow
再次逆转Android。下面是CursorWindow
的构造函数:
public CursorWindow(String name) {
mStartPos = 0;
mName = name != null && name.length() != 0 ? name : "<unnamed>";
if (sCursorWindowSize < 0) {
/** The cursor window size. resource xml file specifies the value in kB.
* convert it to bytes here by multiplying with 1024.
*/
sCursorWindowSize = Resources.getSystem().getInteger(
com.android.internal.R.integer.config_cursorWindowSize) * 1024;
}
mWindowPtr = nativeCreate(mName, sCursorWindowSize);
if (mWindowPtr == 0) {
throw new CursorWindowAllocationException("Cursor window allocation of " +
(sCursorWindowSize / 1024) + " kb failed. " + printStats());
}
mCloseGuard.open("close");
recordNewWindow(Binder.getCallingPid(), mWindowPtr);
}
可以看到,sCursorWindowSize
是CommonsWare提到的大小:
sCursorWindowSize = Resources.getSystem().getInteger(
com.android.internal.R.integer.config_cursorWindowSize) * 1024;
因为我当前的版本是Android SDK 23.0.1
,所以com.android.internal.R.integer.config_cursorWindowSize
的值是2048。意思是2MB。我没有另一个版本SDK用于检查。
Cursor不包含内存中的所有结果,但它确实包含返回查询的总数(通过getCount)。当你迭代的结果,它获取条目(不是一个接一个我猜,但可能在块)。我很确定在这个层面上有优化。一旦你完成了它,你必须关闭它,否则为什么系统会在查询已经完成后保持它打开。