MySQL Fulltext search vs Elasticsearch
Después de un tiempo sin decir nada volvemos por aquí a dar la brasa. Aprovechando los posts que hicimos sobre Elasticsearch y MySQL fulltext search os contamos nuestra experiencia en un caso real.
Llevábamos un tiempo trabajando en mejorar un buscador de una página web. De entrada estaba hecho con el típico LIKE de MySQL con algunos cálculos añadidos para tener algo parecido a una puntuación y poder mostrar los resultados ordenados por ella. Así como estaba montado teníamos varias problemáticas que hacían que esa búsqueda fuese un cuello de botella:
- Los datos sobre los que buscar no estaban en una sola tabla, eran varias. Teníamos que tirar de unions.
- Los campos sobre los que hacíamos LIKE eran de texto y podían ser muy grandes.
- El cálculo de la puntuación no era muy eficiente.
- Sumemos a todo lo anterior muchos registros. Entre 150K y 200K. Y creciendo cada día.
Llegados a este punto nos planteamos 3 opciones: Elasticsearch, Algolia o usar los índices fulltext de MySQL.
La solución
Al final después de muchas pruebas y vueltas acabamos tirando por la opción del índice fulltext de MySQL. Los problemas anteriores los solucionamos así:
- Desnormalizamos los datos de las distintas tablas en una. Esa tabla contiene el índice fulltext. Así nos evitamos hacer unions.
- Dejamos de usar like y utilizamos las opciones propias de la búsqueda de texto fulltext.
- La propia búsqueda fulltext nos da una puntuación que podemos usar para ajustar los resultados.
- Montamos un proceso que cada vez que se actualiza algún dato de las tablas originales se actualiza también en la tabla desnormalizada. Así nos aseguramos hacer las búsquedas contra datos actualizados.
El porqué
La verdad es que cuando discutíamos pros y contras de cada cosa nos dimos cuenta que la mejor opción era la que teníamos más cerca. Varias razones nos ayudaron a decidirnos a ello:
- Utilizar Algolia o Elasticsearch implicaba meter un stack más en el desarrollo. Siempre estábamos a tiempo de hacer algo así. No veíamos razón a añadir más complejidad si no había necesidad. Decidimos darle una oportunidad al MySQL fulltext.
- Además, Algolia era un servicio de terceros y de pago. El índice fulltext no implicaba ningún coste adicional y desde luego es más fácil que un día Algolia deje de funcionar a que lo haga MySQL.
- En cualquiera de los casos teníamos que hacer un proceso que “desnormalizara” los datos de las tablas sobre las que teníamos que hacer una búsqueda.
En conclusión
Hicimos pruebas de estrés y la verdad que la mejora ha sido muy grande. Probablemente en cuanto a velocidad no sea comparable a Elasticsearch. Pero ya de por sí la mejora ha sido notable y hemos eliminado un cuello de botella importante.
Siempre estaremos a tiempo de meter una de las otras dos tecnologías que probamos. Pero nos parecía un poco insensato no darle una oportunidad a algo que está de serie, que no nos implicó mucho trabajo y no añadía ninguna complejidad extra a la arquitectura del proyecto. Igual a veces la solución no es la más molona y está más cerca de lo que pensamos.