Ionic y PouchDB: tips para rendimiento


En la semana he recibido un par de consultas que me parecen super importantes y que trataré de responder en un par de post y de pasada repasar los fundamentos.

La segunda pregunta que recibí creo que es mejor tratarla primero: ¿Ionic con PouchDB y Cloudant es más rápido que usar MySQL y websql? Veamos, desde mi punto de vista por más que parece lo mismo, no lo son.

Antes debemos revisar un par de puntos:

Primero, PouchDB es además una capa de abstracción de datos porque puede utilizar varios tipos de archivos para almacenar los datos (Adaptadores), principalmente puede usar IndexedDB, WebSQL y otros menos usados. La recomendación es que le indiquemos a PouchDB que utilice WebSQL si queremos que sea más rápido. En alguna eventualidad, PouchDB nos libra del problema pues puede elegir automáticamente cual es el mejor almacenamiento para nuestros datos.

Segundo, WebSQL, sqlite o como lo quieran llamar, es un estándar que ya está “depreciado”. El consorcio que maneja los estándares de Internet ya ha fijado que IndexedDB sea el estándar. Los navegadores siguen teniendo soporte para WebSQL pero no se sabe exactamente hasta cuando, mas bien IndexedDB es una obligación para todos.

Ahora comparemos:

PouchDB y Cloudant (o CouchDB en general) es realmente una solución de gestión de datos de extremo a extremo que parte del concepto denominado “offline first” donde la aplicación cliente, luego de una sincronización inicial, está preparada para trabajar sin conectarse al Servidor. Incluso, hay otro movimiento más radical denominada “No Backend”, pero no lleguemos a extremos, de alguna manera la base de datos es el backend y, si fuera necesario, se puede colocar una capa de lógica intermedia. Para resumir, PouchDB – CouchDB incluye, gestión de datos, sincronización y segmentación de datos. Un aspecto adicional es que, dado que no hay esquemas, es necesario “transformar” los datos del modelo relacional para que cuadre en el modelo “documental” de CouchDB y para esto pensaremos en la estructura que mejor nos acomode en la aplicación cliente lo que significa que vamos a “limpiar” el modelo para tener solamente lo que nos interesa.

MySQL y WebSQL (o sqlite para los amigos) es en el sentido estricto solamente un gestor de datos. Pasar datos desde MySQL a la base local en WebSQL es algo que tenemos que hacer nosotros, al igual de la segmentación de datos. Además, dado que en sqlite tenemos tablas y un dialecto de SQL, nuestra primera tentación será la de repetir el modelo de datos que tenemos en el backend.

Entonces, para comparar papas con papas, hablemos del aspecto de gestión de datos solamente de ambas soluciones. La verdad dura y simple es que consultar datos con sqlite es más rápido que consultar datos con PouchDB. Hay un documento que explica el rendimiento comparado de las bases de datos en el lado del cliente que pueden consultar Comparación datos móviles

Ahora bien, esto no me parece determinante porque, dependiendo del modelo de datos que tengamos, es muy probable que con el modelo relacional de sqlite tengamos que hacer más consultas que con PouchDB. Esto no tengo como sustentarlo en números, pero en los proyectos que he realizado es algo evidente que si modelas bien, consultas menos y dado que en un “Documento” de CouchDB puedes organizar los datos en más de 1 nivel, puedes traer más datos en una sola consulta.

Otro punto importante es la cantidad de datos. Mientras más datos tengas, será más claro el tema de la velocidad. En mi caso, tengo apps donde guardo mas de 300 documentos en el móvil y la velocidad es aceptable. Debemos considerar que los documentos no son tan simples, incluso la gran mayoría contiene BLOBs de 20K en promedio de tamaño con un tamaño total de 12 MB de la base de datos, lo que sería una locura en un entorno sqlite. Si el volumen de datos que vas a manejar es menor a mi ejemplo, entonces la diferencia de performance no la vas a sentir.

Guardo el tema de índices para el final porque es muy importante. Con Sqlite podemos crear índices donde y cuando nos dé la gana lo cual casi no tiene costo en procesamiento ni en almacenamiento. En el caso de PouchDB, los índices no se hacen por nada: Existe un índice por defecto que solamente contiene el campo _id de todos los documentos en la base de datos, y como no hay tablas pues estamos hablamos de absolutamente todos los registros. Suena a limitación, pero significa que recuperar un registro es super mega extra rápido y recuerden que un registro puede tener mucha información que en Sqlite podría tomar más de una consulta, además, si usamos el ID correcto nuestras consultas pueden beneficiarse de este super índice: la clave es crear los IDs manualmente incluyendo los criterios de búsqueda que necesitemos. Por ejemplo, si queremos guardar un documento para el Comic 1 de la editorial DC que salió en 01 de febrero del 2015, el ID que nos convendría sería com_dc_2015-02-01_01, de esta manera podremos hacer consultas muy rápidas con el método allDocs de PouchDB:

– Todos los comics: startkey: ‘com_’, endkey: ‘com_\uffff’;

– Todos los comics de la editorial DC: startkey: ‘com_dc_’, endkey:’com_dc_\uffff’

– Todos los comics de DC que salieron el 2015: startkey: ‘com_dc_2015_’, endkey: ‘com_dc_2015_\uffff’

La mala palabra en PouchDB es ‘Joins’ al estilo sql. No existe, así de simple, pero no desesperen pues existen muy buenas alternativas. Aquí van dos: Podemos crear vistas que son parecidas a las del mundo relacional pero que siguen el modelo Map/Reduce que es lo mejor en lo referido a escalabilidad, igual la recomendación es usarla solamente en condiciones extremas tal como se explica en este artículo. La segunda opción se llama Mango y es una forma de indexar toda la base de datos de la forma que nos de la gana y podrán encontrar información aquí.

Finalmente, y creo que es la razón definitiva por la cual se debería usar el modelo con PouchDB, es que tenemos que valorar que estamos usando una solución completa para el manejo de datos, no es solamente un modo de tener una base local, es una solución de sincronización. En un modelo Sqlite, la sincronización es un proceso que tiene que ocurrir de modo secuencial, es decir: ingresas datos, modificas datos, parar para sincronizar, lees datos, modificas datos. Con PouchDB, la sincronización es un proceso que se ejecuta en una tarea paralela, por lo que podremos ingresar, leer, modificar datos sin parar.

Si realmente necesitan velocidad, Sqlite no va a estar en el vecindario por mucho tiempo, así que mi recomendación está en mejorar el modelo.




    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s



%d bloggers like this: