查询批量数据时,第一次光标操作太慢。怎么解决?

时间:2012-02-15 07:20:37

标签: 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个,只需要3s。

提前感谢!!

2 个答案:

答案 0 :(得分:15)

这是为什么光标上的第一个操作太慢的原因。当SQLite支持Cursor时,Android在内部使用sqlite C库,创建Cursor类似于在C库中创建预准备语句。创建预准备语句很便宜,并且不执行任何查询。取自C库的文档:

  

<强> sqlite3_prepare()

     

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

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

  

<强> sqlite3_step()

     

此例程用于评估先前由sqlite3_prepare()接口创建的预准备语句。对语句进行评估,直至第一行结果可用。要前进到第二行结果,再次调用sqlite3_step()。继续调用sqlite3_step()直到语句完成。不返回结果的语句(例如:INSERT,UPDATE或DELETE语句)在单次调用sqlite3_step()时运行完成。

因此,懒惰地创建Cursor并且仅在首次移动光标时评估查询。

要找出查询花费这么长时间的原因,请在查询中使用EXPLAIN QUERY PLAN并查看瓶颈所在的位置。通常情况下,缺乏适当的指数。

答案 1 :(得分:1)

好吧,大家好,我已经好几天了。我找到了解决方案,你必须为你的表创建索引,这将提高查询速度。谢谢所有相同的