android - 查询大量数据时,第一次游标操作很慢。怎么解决?

标签 android sqlite

我必须查询三个表,并将数据显示到我的 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/

相关文章:

android - 播放视频时禁用Android的VideoView requestAudioFocus?

android - 清除 fragment 中的操作栏

android - 如何使 Rx 请求更快地划分为单独的线程?

java - Sqlite插入和更新其他列的值

android - sql语句中同一个查询的多个case和order_by?

java - 从 adb shell 运行基于 android java 的命令行实用程序

android - Qt 5.2 RC1 "Exec format error": android deployment on virtual Ubuntu 13. 04

android - 如何在 Room DB 中创建实体并使用某些字段扩展其他类

ios - 更新使用数据库的应用程序

python - 从应用程序代码内部使用 Alembic API