当查询大容量数据时,第一次游标操作非常慢.如何解决



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

所以我的问题是,为什么第一次光标操作要花这么长时间?我们该如何解决?

这个人也有同样的问题——糟糕的SQLite实现?第一次数据访问速度太慢。但答案对我不起作用。顺便说一句,我发现在Iphone上显示同样的1500行,只需要3秒。

提前感谢!!

这就是为什么对光标的第一次操作如此缓慢的原因。当Cursor由SQLite支持时,Android在内部使用SQLite C库,创建Cursor类似于在C库中创建准备好的语句。创建一个已准备好的语句很便宜,而且它不执行任何查询。取自C库的文档:

sqlite3_prepare()

此例程将SQL文本转换为准备好的语句对象,并返回指向该对象的指针。此接口需要一个数据库连接指针,该指针由先前对sqlite3_open()的调用创建,并需要一个包含要准备的SQL语句的文本字符串此API实际上并不评估SQL语句。它只是为评估准备SQL语句

当您在Cursor上调用moveToNext()时,查询实际上是被执行的。moveToNext导致对C库中的sqlite3_step()函数的调用。再次,取自文件:

sqlite3_step()

此例程用于评估先前由sqlite3_prepare()接口创建的已准备语句。该语句的求值一直到第一行结果可用为止。要进入结果的第二行,请再次调用sqlite3_step()。继续调用sqlite3_step(),直到语句完成。不返回结果的语句(例如:INSERT、UPDATE或DELETE语句)只需调用sqlite3_step()即可运行完成。

因此,创建游标是惰性地完成的,并且只有在第一次移动游标时才计算查询。

要找出查询花费如此长时间的原因,请在查询中使用EXPLAIN QUERY PLAN并查看瓶颈所在。通常是因为缺乏合适的索引。

好了,伙计们,我已经好几天没来了。我发现了一个解决方案,那就是你必须为你的表创建索引,这将提高查询速度。感谢所有相同的

最新更新