Bucle a través de un Cursor SQLite lleva demasiado tiempo
Estoy utilizando una SQLite
datos SQLite
en una aplicación de Android y el método getAll
que he escrito toma demasiado tiempo en mi opinión.
Este es el código que estoy hablando:
- SQLite en Android Cómo actualizar una fila específica
- Sqlite: parece que moveToNext funciona sin moverToFirst necesario
- Android SQLiteConstraintException: código de error 19: error de restricción
- La aplicación se bloquea al iniciar Debido a java.lang.IllegalArgumentException: la columna '_id' no existe
- Eliminar todas las filas de una tabla, lanza nullpointer
public static List<Feed> getAll(Context context) { List<Feed> feeds = new ArrayList<Feed>(); Uri allFeeds = Uri.parse(ContentProvidersUris.URL_CONTENT_PROVIDER_FEED); long startQuery = BenchmarkUtils.start(); Cursor c = context.getContentResolver().query(allFeeds, null, null, null, "title desc"); long startCursor = BenchmarkUtils.start(); for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { long startInsideCursor = BenchmarkUtils.start(); Feed feed = new Feed(); feed.setContent(c.getString(c.getColumnIndex(FeedsProvider.COL_WEBVIEW_CONTENT))); feed.setDate(c.getString(c.getColumnIndex(FeedsProvider.COL_PUB_DATE))); feed.setDescription(c.getString(c.getColumnIndex(FeedsProvider.COL_DESCRIPTION))); feed.setName(c.getString(c.getColumnIndex(FeedsProvider.COL_FEED_NAME))); Log.d(TAG, "This loop cursor iteration took : " + BenchmarkUtils.stop(startInsideCursor) + " ms."); } Log.d(TAG, "Looping through the ENTIRE Cursor took: " + BenchmarkUtils.stop(startCursor) + " ms."); return feeds; }
Como se puede ver también estoy midiendo el tiempo que toma este bucle en cada iteración y resulta que toma un tiempo promedio de 1800 ms (en un Nexus S
). Me parece que esto es mucho tiempo. Y lo que no entiendo es que la mayor parte de este tiempo se gasta en la primera iteración como se muestra en los registros:
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1726 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 3 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 2 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 0 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 5 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 5 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D / FeedsProviderHelper (5800): Esta iteración del cursor de bucle tomó: 1 ms.
D / FeedsProviderHelper (5800): Bucle a través del Cursor ENTIRE tomó: 1770 ms.
Así que mis preguntas son:
¿Es normal? ¿Si es así por qué? Si no, ¿qué estoy haciendo mal? Cualquier forma más rápida de hacer un selectAll
contra la base de datos SQLite?
¡Gracias!
EDITAR
Tomé las llamadas de getColumnIndex
fuera del lazo como @superfell sugirió, y ahora estoy funcionando el método de getAll
en un promedio 1500ms . Es más rápido pero no lo suficientemente rápido en mi opinión (de nuevo)!
- Almacenamiento y recuperación de datos no ingleses en la base de datos sqlite en android
- Android: la columna '_id' no existe
- SQLiteException: Token no reconocido al leer de la base de datos
- Actualizar la tabla sqlite en android
- En java, ¿cómo puedo eliminar una tabla sqlite?
- ¿Cuál es el modo de subprocesamiento predeterminado de SQLite en Android?
- InsertWithOnConflict () vs. Insertar o reemplazar
- SQLite agregar columna, mantener datos
¿Es normal?
Por supuesto.
¿Si es así por qué?
E / S de disco es cara, especialmente en flash. La consulta en sí se ejecuta en su primera solicitud real contra el Cursor
, por lo que su primera "iteración" tarda mucho más.
Cualquier forma más rápida de hacer un selectAll contra la base de datos SQLite?
En primer lugar, no estás haciendo un "selectAll" contra una base de datos SQLite. Estás haciendo un "selectAll" contra un proveedor de contenido.
Utilice Traceview para determinar con precisión dónde se va a tomar su tiempo y sintonice su aplicación en consecuencia. Por ejemplo, podría encontrar que tiene más sentido no copiar datos de un Cursor
en una lista de POJOs en primer lugar.
Lo primero que debe hacer es tomar las llamadas getColumnIndex fuera del bucle, son caras, y sólo es necesario hacerlas una vez, no para cada fila.