我必须查询三个表,并将数据显示到我的 customerView。
我的代码是这样的:
Log.v(TAG, System.CurrentTimeMillis())
int len = cursor.getCount();
Log.v(TAG, System.CurrentTimeMillis())
Product[] products = new Product[len];
int i = 0;
while(cursor.moveToNext()){
products[i] = new Product(cursor.getstring(0),.....);
}
Log.v(TAG, System.CurrentTimeMillis())
SQLite 查询:
String sql = "SELECT T1.PRODUCT_ID, CODE, SHORT_DESCRIPTION, CATEGORY_CODE,
BRAND_CODE, FORM_CODE, DENOMINATOR, T1.PIECE_PRICE, T1.lowest_piece_price,
T2.sku_type, T1.master_sku " +
"FROM CUSTOMER_PROD_LIST_ITEMS T1 INNER JOIN PRODUCT T2 ON
T1.PRODUCT_ID = T2.ID INNER JOIN PRODUCT_UOMS ON T2.ID =
PRODUCT_UOMS.PRODUCT_ID"+
"WHERE T1.VALID = 1 AND PRODUCT_UOMS.VALID = 1 AND
CUSTOMER_PRODUCT_LIST_ID = " + customer_pdtlist_ID + "
ORDER BY T1.PRODUCT_ID ASC";
经过我的测试,如果游标中有 1500 行,我们必须花费 30 多秒才能完成这一行 (cursor.getcount()) 。如果我删除这一行,并使用 ArrayList 来代替。我发现我们应该为 Cursor.moveToNext() 花费超过 30 秒。
所以我的问题是为什么第一次光标操作要花这么长时间?我们如何解决?
和这个人有同样的问题Poor SQLite implementation? First time data access way too slow .但答案对我不起作用。 顺便说一句,我发现在 Iphone 中显示相同的 1500 行,只需要最多 3 秒。
提前致谢!!
最佳答案
这是对为什么您的光标上的第一个操作如此缓慢的答案。当 SQLite 支持 Cursor 时,Android 在内部使用 sqlite C 库,创建 Cursor
类似于在 C 库中创建准备好的语句。创建准备好的语句很便宜,而且它不执行任何查询。摘自 C 库的文档:
sqlite3_prepare()
This routine converts SQL text into a prepared statement object and returns a pointer to that object. This interface requires a database connection pointer created by a prior call to sqlite3_open() and a text string containing the SQL statement to be prepared. This API does not actually evaluate the SQL statement. It merely prepares the SQL statement for evaluation.
当您在 Cursor
上调用 moveToNext()
时,查询将实际上 执行。 moveToNext
导致调用 C 库中的 sqlite3_step()
函数。同样,取自文档:
sqlite3_step()
This routine is used to evaluate a prepared statement that has been previously created by the sqlite3_prepare() interface. The statement is evaluated up to the point where the first row of results are available. To advance to the second row of results, invoke sqlite3_step() again. Continue invoking sqlite3_step() until the statement is complete. Statements that do not return results (ex: INSERT, UPDATE, or DELETE statements) run to completion on a single call to sqlite3_step().
因此创建 Cursor 是延迟完成的,并且仅在第一次移动光标时才评估查询。
要找出为什么查询花费这么长时间,请使用 EXPLAIN QUERY PLAN
在您的查询中查看瓶颈所在。通常是缺少合适的索引。
关于android - 查询大量数据时,第一次游标操作很慢。怎么解决?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9289369/