android - not - La primera vez que el Cursor funciona es tan lento, cuando consulta datos a granel. ¿Cómo resolver?
sqlite3 commands (2)
Tengo que consultar tres tablas y mostrar los datos a mi customerView.
Mi código es así:
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())
Consulta 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";
Después de mi prueba, si tenemos 1500 líneas en el cursor, tenemos que pasar más de 30 segundos para terminar esta línea (cursor.getcount ()). Si elimino esta línea, y uso ArrayList para tener lugar. Puedo encontrar que deberíamos gastar más de 30s para Cursor.moveToNext ().
Entonces mi pregunta es ¿por qué la operación del cursor por primera vez debería tomar tanto tiempo? y ¿cómo resolvemos?
Y este hombre tiene la misma pregunta. ¿ Mala implementación de SQLite? El acceso a datos por primera vez es demasiado lento . pero la respuesta no funciona para mí. por cierto, creo que la pantalla muestra los mismos 1500 fondos en Iphone, solo necesito un máximo de 3s.
¡¡gracias por adelantado!!
Esta es una respuesta a por qué la primera operación en el cursor es tan lenta. Cuando un Cursor está respaldado por SQLite, Android usa la biblioteca sqlite C internamente y la creación de un Cursor
es análoga a la creación de una declaración preparada en la biblioteca C. Crear una declaración preparada es barata y no realiza ninguna consulta. Tomado de la documentación de la biblioteca C:
sqlite3_prepare ()
Esta rutina convierte texto SQL en un objeto de declaración preparado y devuelve un puntero a ese objeto. Esta interfaz requiere un puntero de conexión de base de datos creado por una llamada previa a sqlite3_open () y una cadena de texto que contiene la declaración de SQL que se preparará. Esta API en realidad no evalúa la declaración SQL. Simplemente prepara la declaración SQL para la evaluación.
Cuando llamas a moveToNext()
en el Cursor
, es cuando la consulta realmente se ejecuta. moveToNext
da moveToNext
resultado una llamada a la sqlite3_step()
en la biblioteca C. Nuevamente, tomado de la documentación:
sqlite3_step ()
Esta rutina se usa para evaluar una declaración preparada que ha sido creada previamente por la interfaz sqlite3_prepare (). La declaración se evalúa hasta el punto donde la primera fila de resultados está disponible. Para avanzar a la segunda fila de resultados, invoque sqlite3_step () nuevamente. Continúe invocando sqlite3_step () hasta que la declaración esté completa. Los enunciados que no devuelven resultados (por ej .: instrucciones INSERTAR, ACTUALIZAR o ELIMINAR) se ejecutan por completo en una sola llamada a sqlite3_step ().
Entonces la creación de un Cursor se realiza de forma perezosa y la consulta solo se evalúa cuando se mueve el cursor por primera vez.
Para averiguar por qué la consulta lleva tanto tiempo, use EXPLAIN QUERY PLAN
en su consulta y vea dónde se encuentra el cuello de botella. Por lo general, es la falta de un índice apropiado.
Bien, muchachos, no he estado aquí por unos días. Y encontré la solución que es que tienes que crear un índice para tu tabla que mejorará la velocidad de la consulta. gracias de todos modos