Rendimiento de Access contra backend Access en servidor de archivos remoto. Tercera parte.
En anteriores artículos de la serie, Rendimiento de Access contra backend Access en servidor de archivos remoto. Primera parte. y Rendimiento de Access contra backend Access en servidor de archivos remoto. Segunda parte. pudimos ver que el rendimiento de Access como BackEnd es más que aceptable en consultas sencillas incluso con tablas de 500.000 registros:
Como podéis observar, ninguna de las consultas llega a media décima de segundo. Si revisáis el anterior artículo, veréis que realmente los tiempos son despreciables y dependen más del estado de la red que de la optimización de las consultas en sí. Viendo estos resultados podíamos pensar que Access es tan válido como cualquier SGBD de servidor (Oracle, SQL-Server, MySql, Microsoft Azure, etc.) y en cierto sentido tendríamos razón. Lo que no podemos olvidar es que los SGBD disponen de otro tipo de características que hacen que sean más apropiados en sistemas multiusuario como Backups, manejo de la concurrencia, manejo de errores, seguridad y sobre todo capacidad de proceso de operaciones muy superior a Access.
Pues nada, entonces aquí termina el artículo, la serie y el blog. Access no vale para este tipo de escenarios multiusuario y en red ¿verdad?
Los que ya me conocéis sabréis que no estoy para nada de acuerdo. Partiendo de la base de que los SGBD orientados a servidor pueden ser una herramienta óptima para este tipo de proyectos, hay veces que no es posible montarlos en nuestros sistemas y creo que Access puede ser lo suficientemente seguro y potente como para utilizarlo en la gran mayoría de sistemas de base de datos medios.
Así que vamos a empezar con las pruebas un poco más «cañeras». En este artículo vamos a probar varios tipos de consultas (de momento seguimos con las selección, ya iremos viendo otros tipos de manipulaciones de datos), incrementando la carga de proceso. En resumen, vamos a darle caña al motor de base de datos Access.
Voy a volver a describir un poco el escenario para los que no hayáis leído el resto de artículos (recomiendo su lectura…):
- BackEnd: Base de datos Access alojada en servidor de archivos. 20 tablas correctamente relaciones y normalizadas siguiendo el modelo relacional.
- FrontEnd: Aplicación Access y VBA.
- Red: Servidor de archivos en otra provincia, red corporativa dedicada.
- Tablas de prueba: Se harán pruebas con tablas sin índices y con índices. Se utilizarán 4 tablas con 67.000, 59.000, 3.200 y 9.000 registros respectivamente. Edito: Segunda prueba. Tablas de 500.000 registros
- Consultas: Varios tipos. Devuelven valores entre 41 registros y 372.492 registros (si, habéis leído bien). Edito: Segunda prueba. Consultas con 2.000.000 de registros
- Pruebas: Se realizarán las pruebas en tandas de 100, utilizando bucles para ello. Para que los resultados sean más fiables, se realizará cada tipo de prueba seguido del siguiente, evitando así que influya el estado de la red
- Concurrencia: Como he comentado, las pruebas principales se realizaron de noche, por lo que no hay usuarios conectados. Gracias a José Antonio Pérez me di cuenta que puede ser importante realizar las mismas pruebas con los usuarios conectados a la base de datos, así que las he realizado desde el equipo de un compañero.
Como podéis ver, he realizado varias series de pruebas con las mismas consultas. En este caso vamos a utilizar sobre todo consultas de Access (generador de consultas) y consultas Pass Through emulado:
Prueba 1: 4 tablas con 67.000, 59.000, 3.200 y 9.000. Devuelven valores entre 41 registros y 372.492 registros. Sin concurrencia
Prueba 2: 4 tablas con 11.000, 5.000, 3.200 y 9.000. Devuelven valores entre 41 registros y 17.000 registros (lo siento, no he podido realizarlas con más registros, es «fuego real»…). 30 usuarios conectados.
Prueba 3: 4 tablas con 500.000, 300.000, 3.200 y 9.000. Devuelven valores entre 41 registros y 2.584.580 registros.
Prueba 1
En esta prueba utilizaremos sobre todo las consulta que he llamado «Larga» (tenía un día poco inspirado). La consulta devuelve 372.492 sin utilizar filtros y se utilizan las 4 tablas con LEFT JOIN (que se supone que no funcionaba muy bien con el motor de base de datos Access. Las variaciones de la consulta las iré explicando sobre la marcha. Aquí van los resultados, primero en tablas con índices:
Como podéis ver, esta vez los tiempos empiezan a acercarse al segundo, incluso lo sobrepasan en algún caso. Ahora sí que podemos sacar alguna conclusión ya que los tiempos empiezan a depender más de las propias consultas que del estado de la red. Si queréis saber a qué corresponde cada tipo de consulta, están explicadas en el anterior artículo sobre Rendimiento de Access, sobre todo las que emulan Pass Through. La única novedad es el uso del operador LIKE, que según comentaban, hacía que el motor de base de datos de Access no funcionara correctamente. He introducido 2 tipos de consultas con LIKE, la primera metiendo un par de criterios en 2 campos y la segunda poniendo LIKE * en esos mismos campos (tenía curiosidad…).
Antes de sacar conclusiones, voy a postear la misma prueba pero esta vez con las tablas sin índices, para ver si la optimización hace algo:
Conclusiones
La conclusión más clara que he podido sacar realizando estas pruebas es que en general funciona bastante mejor realizar las consultas con DAO y emulando Pass Through que con el generador de consultas de Access. En algunos casos los tiempos se dividen por 2.
Por otro lado, vemos que en cuanto empezamos a meter carga de proceso, los tiempos suben bastante. Los LEFT JOIN y sobre todo la carga de realizar las consultas con LIKE, hace que varias se acerquen al segundo.
Y por último, vemos que los mejores resultados se dan en consultas filtradas, algo que parece lógico, pero solo en tablas bien indizadas. Cuando quitamos los índices de las tablas, vemos que una de las consultas con WHERE se nos hace más pesada incluso que la consulta sin filtrar. Pienso que es por la carga de proceso del propio filtro, que en este entorno de red (bastante rápido) pesa más que el traslado de datos.
Prueba 2
Como habéis visto, no he podido realizar las pruebas con usuarios conectados («fuego real») contra las tablas anteriores. Probablemente por eso, los tiempos son muy parecidos (incluso mejores en algunos casos). Pero bueno, ahí queda como muestra de que consultas más complejas que las del artículo anterior, funcionan bien incluso con bastantes usuarios concurrentes. También tengo que decir que utilizo formularios desconectados, que quitan bastante carga, pero de eso ya hablaremos en artículos posteriores:
Podéis ver que aquí ya no funcionan tan bien las consultas emulando Pass Through y DAO (creo que no es la mejor opción, aunque probablemente sea mejor que las consultas Access).
Prueba 3
Y ahora vamos con la «picada» con @ManejandoDatos. Aquí tenéis su Tweet:
Como explicaba en el artículo anterior, no he llegado al millón de registros, pero sí a los 500.000. Las tablas quedan con 500.000, 300.000, 3.200 y 9.000 registros y una de las consultas devuelve 2.584.580. Aquí van los resultados:
En esta prueba sin índices seguimos viendo algo que me ha resultado muy curioso. Cuando hablamos de consultas Access creadas con el diseñador de consultas, tardan más las que tienen criterios. Podríamos pensar que es, o por carga de proceso, o porque el motor de base de datos no es capaz de enviarla al servidor y tiene que recuperar todos los registros antes de filtrar. Veamos las pruebas con índices para aclarar esto (Aunque era para el siguiente artículo, he añadido pruebas con DAO y ADO filtradas con WHERE pero esta vez sin emular, directamente con consultas SQL contra la base de datos abierta en el servidor. No he podido resistirme…):
Ahora sí, aquí ya vemos diferencias de tiempos significativas entre consultas optimizadas y consultas sin optimizar. Curiosamente la consulta sin filtrar tarda bastante más que en la prueba sin índices, probablemente porque los datos pesen más una vez indizados, pero vemos que los tiempos para consultas indizadas son muy parecidos a pruebas anteriores con muchos menos registros.
Vemos que incluso las consultas emulando Pass Through son mucho más rápidas si filtramos correctamente y sobre todo vemos que tanto con ADO como con DAO (curiosamente DAO siempre da mejores tiempos… ya sabéis lo que opino de DAO y ADO), los tiempos son buenísimos. Me gustaría tener pruebas de este tipo para SGBD de servidor (todo llegará), pero creo que todos firmábamos estos tiempos para consultas de este estilo.
En el siguiente artículo realizaremos las pruebas de selección que más carga de proceso tienen, las de valores únicos utilizando DISTINCT. En esas pruebas podremos ver realmente la diferencia de las consultas Access tanto con DAO como con ADO y veremos la importancia de filtrar correctamente y optimizar nuestras consultas.
photo credit: BobMical via photopin cc
Arkaitz Arteaga
Latest posts by Arkaitz Arteaga (see all)
- Access: Encriptar contraseñas con SHA-256 utilizando biblioteca de clases .NET con C# - 4 mayo, 2014
- Rendimiento de Access contra backend Access en servidor de archivos remoto. Cuarta parte. - 27 abril, 2014
- Rendimiento de Access contra backend Access en servidor de archivos remoto. Aclaración. - 21 abril, 2014
- Utilizar biblioteca de clases .NET en Access. Tercera aproximación a la Interoperabilidad COM - 14 abril, 2014
- Vincular tablas en Access con Visual Basic - 11 abril, 2014