Es bien sabido que los recursos son muy limitados en entornos de producción y que es cierto que ahora existen servidores diez veces más potentes que los que existían hace 5 años, sin embargo así como ha subido la potencia de estos equipos también lo ha hecho la consulta de datos.
Dependiendo de la cantidad de tiempo que se tarde una consulta en ejecutarse podemos decir si es crítica o no, sin embargo aunque no sea crítica siempre hay un pequeño margen para mejorar, con ello ahorraremos segundos de ejecución que al final del día se transforman en minutos, lo que nos da la posibilidad de mejorar la experiencia de usuario.
También necesitamos un set de datos o documentos para llenar nuestra colección, en tutoriales pasados ofrecimos un set de datos iniciales, sin embargo para quienes no lo tengan pueden utilizar este:
db.guiamongo.insert({"nombre": "Maria", "edad":"25", "genero":"Femenino", "pais":"Colombia" });db.guiamongo.insert({"nombre": "Pedro", "edad":"32", "genero":"Masculino", "pais":"Ecuador" });db.guiamongo.insert({"nombre": "Ramon", "edad":"18", "genero":"Masculino", "pais":"Honduras" });db.guiamongo.insert({"nombre": "John", "edad":"22", "genero":"Masculino", "pais":"Argentina" });db.guiamongo.insert({"nombre": "Rosa", "edad":"45", "genero":"Femenino", "pais":"Chile", "idiomas":["Esp", "Ing", "Fra"] });Con esto tendremos suficiente para un pequeño inicio y así obtener resultados de los ejercicios que presentaremos a continuación.
1. Indexando MongoDB
Indexar o trabajar con índices es un concepto compartido en MongoDB con las Bases de Datos relacionales, es decir, si tenemos una noción de este concepto, podremos entender cómo funciona en MongoDB en poco tiempo, simplemente necesitamos ajustarnos a la sintaxis en particular.
Para crear un índice en MongoDB lo que debemos hacer es utilizar la función ensureIndex() y como parámetro pasar un documento JSON indicando los campos o propiedades de nuestro documento con las cuales debemos conformar dicho índice. Veamos un pequeño ejemplo de esto.
Supongamos que tenemos una colección llamada guiamongo y hacemos una búsqueda por un campo llamado nombre, el código sería este:
db.guiamongo.find({“nombre”: “Nombre”})Esto es una consulta normal la cual no tiene nada en particular, el único problema es que si hay millones de documentos sería muy lenta, entonces para crear un índice solo debemos especificarlo de la siguiente forma:
db.guiamongo.ensureIndex({“nombre”:1})Ya con esto hemos creado el índice para la consulta, si la ejecutamos nuevamente será mucho más rápida. Veamos como luce esto en nuestra consola de MongoDB:
Podemos notar que una vez que creamos el índice, MongoDB nos devuelve un documento donde nos indica el estado de nuestra función y cuantos índices teníamos antes y después de la aplicación, adicionalmente mostrándonos el campo ok en 1 el cual indica que fue exitosa la ejecución.
La consulta anterior es bastante útil para un solo campo pero si realizamos la siguiente:
db.guiamongo.find({“nombre”:”Nombre”, “edad”:{”$gt”:”20”}}).sort({“edad”:-1});Nos damos cuenta que en este caso el índice anterior no funciona ya, esto es debido a que la consulta utiliza una combinación de campos diferente para la búsqueda, es por ello que debemos hacer un nuevo índice utilizando lo aprendido anteriormente, veamos cómo sería:
db.guiamongo.ensureIndex(“nombre”:1, “edad”: 1);Ahora si revisamos como sigue nuestra Base de Datos veremos que tenemos un nuevo índice en la colección:
2. Desventaja en el uso de los índices
A pesar de las grandes ventajas que nos trae el uso y trabajo con índices, estos no siempre son beneficiosos, es por ello que debemos analizar exhaustivamente antes de implementar esta característica en nuestra Base de Datos.
Otra desventaja es que tenemos un máximo de 64 índices por colección, es por ello que debemos trabajar con la menor cantidad de los mismos posibles en nuestra Base de Datos, asegurándonos así que solo lo estrictamente necesario es lo que se utiliza.
3. Cómo saber cuándo debemos utilizar un índice
Ya que sabemos las restricciones y desventajas del uso de los índices un buen ejercicio para saber si debemos crearlos o no es tomar esta serie de preguntas, si las podemos responder todas tenemos las características necesarias para crear un índice, en cambio si no podemos tendremos que analizar la situación desde otro punto de vista, veamos las preguntas:
Por supuesto esto es solo una guía, hay casos especiales y muy particulares de cada administrador de aplicaciones en los cuales debe aplicar su criterio por encima de este tipo de tutoriales, sin embargo es una buena guía para iniciarnos en el mundo de la optimización de datos.
4. Índices dentro de documentos embebidos
La estructura de documentos que podemos manejar en MongoDB se presta para realizar almacenaje complejo de datos, no todos los datos que necesitamos van a estar en un mismo nivel, es por ello que surge la necesidad de crear índices de documentos embebidos. Con dichos índices MongoDB podrá ser capaz de indexar los datos que tiene estructuras más complejas.
Para conseguir un resultado utilizaremos lo que se denomina la dot notation, que no es más que acceder a los campos de los documentos embebidos como si fuesen propiedades de un objeto a través de un punto. En el siguiente ejemplo crearemos un índice de estas características, veamos inicialmente la sintaxis.
Primero vamos a insertar un registro con un documento embebido en nuestro set de datos de prueba:
db.guiamongo.insert({"nombre":"Juan", "edad":"40", "genero":"Masculino", "pais":"Brasil","calificaciones":{"historia":"85","literatura":"90", "curso":"3"} });Luego vamos a hacer una simple consulta en este caso por la propiedad curso:
db.guiamongo.find({“califcaciones.curso”:”3”});Ahora si queremos crear un índice simplemente debemos hacer lo siguiente:
db.guiamongo.ensureIndex({“califcaciones.curso”:1});Ya con esto hemos creado un índice de un documento embebido dentro de otro en una colección en MongoDB. Si nos fijamos esto es lo que debemos haber obtenido en consola:
5. Utilizar explain()
Ya que sabemos crear índices y tenemos una idea de cuándo y por qué debemos crearlos, sin embargo aún no hemos visto una herramienta que es muy importante, una que nos permite saber un poco más e ir más allá en nuestras consultas; nos referimos a explain() esta función nos permite saber el tiempo y los índices utilizados en las consultas.
Veamos cómo podemos aplicar esta función a una consulta, vamos a emplear la que realizamos en nuestro ejemplo anterior:
db.guiamongo.find({“califcaciones.curso”:”3”}).explain();Luego de su aplicación, esta nos debe retornar algo como lo siguiente:
Notamos como se nos ofrecen datos para poder analizar la consulta, en cursor vemos que hemos utilizado el índice que creamos en el ejercicio anterior llamado calificaciones.curso_1, esto nos ayudó a llegar 0 mili-segundos de ejecución que es el tiempo óptimo para nuestras consultas, obviamente al ser este un ambiente de pruebas no tendremos algo más allá, pero si podemos hacer este ejercicio en servidores con millones de registros nos daremos cuenta del poder de los índices.
Con esto hemos finalizado este tutorial, hemos creado índices en nuestras colecciones de documentos y adicionalmente hemos explorado algunas herramientas que nos ayudan a obtener información clave para mejorar y sobre todo aumentar el rendimiento de nuestra Base de Datos.