2012-03-26 17 views
7

Estoy trabajando para desarrollar una aplicación que tiene que consultar en algún momento, una base de datos con más de 4k filas y cada fila tiene 90 campos (Strings) El problema es que si selecciono * desde la base de datos, mi cursor se vuelve realmente grande (más de 4MB). Y el cursor en Android está limitado a 1MB. ¿Cómo puedo resolver esto, o cuál es el método más elegante para solucionar esto? ¿Es posible dividir la base de datos en fragmentos más pequeños y consultarlos?Android cómo consultar una enorme base de datos en android (el tamaño del cursor está limitado a 1MB)

Gracias, Arkde

Respuesta

7

Encontré una manera de manejar esto y quiero compartirlo con todos los que lo necesiten.

int limit = 0; 
    while (limit + 100 < numberOfRows) { 
     //Compose the statement 
     String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ limit+"', 100"; 
     //Execute the query 
     Cursor cursor = myDataBase.rawQuery(statement, null); 
     while (cursor.moveToNext()) { 
      Product product = new Product(); 
      product.setAllValuesFromCursor(cursor); 
      productsArrayList.add(product); 
     } 
     cursor.close(); 
     limit += 100; 
} 

//Compose the statement 
String statement = "SELECT * FROM Table ORDER someField LIMIT '"+ (numberOfRows - limit)+"', 100"; 
//Execute the query 
Cursor cursor = myDataBase.rawQuery(statement, null); 

while (cursor.moveToNext()) { 
    Product product = new Product(); 
    product.setAllValuesFromCursor(cursor); 
    productsArrayList.add(product); 
} 
cursor.close(); 

La idea principal es dividir sus datos, por lo que puede utilizar el cursor como se debe utilizar. Está trabajando por debajo de 2 s para 5k filas si tiene una tabla indexada.

Gracias, Arkde

1

¿Necesita todas estas filas al mismo tiempo? ¿Puedes buscarlos en partes? Esta pregunta se ha hecho varias veces: Android SQLite and huge data sets

Aquí es una sugerencia más: Si usted tiene 90 campos que se necesita para modificar, ellos dividido en 10 diferentes puntos de vista. En cada vista, tenga una flecha hacia la izquierda y una flecha hacia la derecha para que pueda atravesar horizontalmente las pantallas. Por lo tanto, cada vista mostrará 9 campos. O alguna estrategia como esa. Básicamente, estas son todas las mismas vistas, excepto los nombres de columna, por lo que no debería tener que modificar mucho código.

+0

sí, necesito todas estas filas al mismo tiempo, ya que necesito ellas almacenan en un ArrayList para llenar y adaptador para una vista de lista. Y los problemas parecen ser con el tamaño de los objetos almacenados en el cursor no con el número de filas (en la pregunta respondida en su enlace sugerido, hay un problema con el número de filas) – Arkde

+0

El límite se aplica a los datos generales, ya sea se debe a una gran cantidad de filas o columnas realmente grandes o muchas columnas. No conozco otra alternativa que compactar tus datos de alguna manera. – Sid

+0

¿Alguna idea de cómo puedo compactar mis datos? Utilicé String para almacenarlos, ya que el tamaño de la cadena aumenta con el número de caracteres que contiene ...No conozco otra forma de optimizar esto. – Arkde

0

Bueno, como regla, nunca selecciona *. Para empezar, cada fila tendrá un identificador único, y su usuario querrá seleccionar solo ciertas filas y columnas, es decir, lo que pueden ver en una pantalla de Android. Sin parecer grosero, esta es una pregunta bastante básica. Solo devuelve las columnas y filas que desea mostrar para esa pantalla en el teléfono; de lo contrario, consume una vida útil de batería innecesaria y nunca se vuelven a reproducir los datos. el enfoque estándar es para usar procedimientos almacenados parametrizados. Google parametrizó los procedimientos almacenados y leyó un poco, poco a poco, no puede actualizar ninguna tabla, devuelve el identificador de fila único para esa tabla.

+0

Tengo que hacer una selección * porque, desafortunadamente, necesito todos los campos que se utilizarán. El usuario editará algunos de los campos y otros se usarán para diferentes configuraciones. – Arkde

+0

En ese caso, tendré SQL dinámico donde los nombres de campo son generados por el usuario seleccionándolos de una lista de casillas de verificación, más cualquier campo oculto que necesite actualizar, luego vaya a una vista de detalles. También puede hacer una declaración de actualización dinámica. Todavía no sé cómo se obtienen todos esos datos en una pantalla típica de Android. –

2

Ian P tiene toda la razón. Para ampliar su respuesta, si tiene 90 campos, probablemente no esté utilizando las estrategias más eficientes. Debe tener varias tablas, que vincula por ID. NUNCA debe meter todas las variables que puede o no necesitar en una sola tabla. ES POR ESO que excede el tamaño. Incluso si solo copiara una hoja de cálculo de Excel masiva con 90 columnas, debe diseñar solo para recuperar algunas a la vez. Un usuario móvil NO va a esperar esa consulta. Ellos no lo harán. @ 3G velocidades que está exigiendo MUCHO a sus usuarios potenciales. No solo les pides que se sienten y esperen mientras ven literalmente que nada pasa durante ~ 5 minutos, sino que también estás exigiendo esencialmente una preciosa duración de la batería.

1MB es generoso. Si recupera datos según sea necesario y utiliza estrategias de codificación eficientes, 1MB será más de lo que necesitará.

Cuestiones relacionadas