
Optimizar PostgreSQL y MariaDB en servidores Linux no significa cambiar parámetros al azar. El rendimiento real se consigue midiendo consultas, revisando índices, ajustando memoria, controlando el almacenamiento, manteniendo estadísticas actualizadas y monitoreando el comportamiento del sistema antes y después de cada cambio.
PostgreSQL y MariaDB pueden funcionar muy bien con configuraciones predeterminadas en entornos pequeños, pero las aplicaciones empresariales, tiendas en línea, sistemas de facturación, ERPs, CRMs, portales web y plataformas de analítica requieren una revisión más cuidadosa. PostgreSQL documenta herramientas como EXPLAIN, VACUUM, ANALYZE, pg_stat_statements y auto_explain; MariaDB documenta el slow query log, EXPLAIN, ANALYZE TABLE, estadísticas de índices e InnoDB Buffer Pool como piezas importantes del diagnóstico.
Conclusión rápida: primero identifica consultas lentas, luego revisa planes de ejecución, después crea o corrige índices, actualiza estadísticas y recién entonces ajusta memoria, conexiones, almacenamiento y parámetros del motor.
Regla de oro: no copies configuraciones de Internet sin medir. Un parámetro que mejora una base de datos analítica puede perjudicar una base de datos transaccional con muchas escrituras.
1. Empieza por una línea base del servidor Linux
Antes de tocar PostgreSQL o MariaDB, debes saber si el cuello de botella está en CPU, memoria, disco, red, bloqueo de consultas o diseño SQL. Un servidor puede parecer “lento” por falta de índices, pero también por I/O saturado, exceso de conexiones, swap, discos lentos o consultas bloqueadas.
Si el servidor utiliza discos mecánicos para cargas transaccionales pesadas, si la memoria está al límite o si la base de datos comparte recursos con demasiados servicios, ningún parámetro mágico resolverá el problema.
2. Diferencia los tipos de carga
| Tipo de carga | Características | Prioridad de optimización |
|---|---|---|
| OLTP | Muchas lecturas y escrituras pequeñas. | Índices precisos, baja latencia, transacciones cortas. |
| Analítica | Consultas pesadas, agregaciones y escaneos grandes. | Memoria, paralelismo, particionado, índices adecuados. |
| Mixta | Transacciones y reportes en la misma base. | Separar reportes, réplicas de lectura y ventanas de mantenimiento. |
| Web | Muchas consultas repetitivas desde una aplicación. | Caché, índices, pool de conexiones, consultas parametrizadas. |
Una base de datos de ventas no se optimiza igual que un sistema de reportes. Por eso la línea base debe incluir número de conexiones, consultas por segundo, tiempo promedio, consultas más costosas, uso de disco y crecimiento de tablas.
3. Optimización en PostgreSQL
3.1. Identifica las consultas más costosas con pg_stat_statements
PostgreSQL incluye la extensión pg_stat_statements, que permite registrar estadísticas de planificación y ejecución de las consultas ejecutadas por el servidor. Es una de las herramientas más útiles para saber qué consultas consumen más tiempo total, cuáles se ejecutan muchas veces y cuáles tienen peor promedio.
3.2. Usa EXPLAIN y EXPLAIN ANALYZE
EXPLAIN muestra el plan que PostgreSQL usará para ejecutar una consulta. Cuando se usa EXPLAIN ANALYZE, la consulta se ejecuta realmente y se muestran tiempos reales, filas procesadas y diferencias frente a las estimaciones. PostgreSQL recomienda usar estos planes para entender cómo el optimizador decide leer tablas, usar índices y unir datos.
Si el plan muestra lecturas secuenciales sobre tablas grandes, muchas filas descartadas por filtros, ordenamientos en disco o diferencias enormes entre filas estimadas y filas reales, probablemente debes revisar índices, estadísticas, diseño de consulta o configuración de memoria.
3.3. Crea índices con criterio
Un índice puede acelerar lecturas, filtros, uniones y ordenamientos, pero también consume espacio y ralentiza escrituras. Por eso no se debe indexar cada columna. La decisión debe basarse en consultas reales, cardinalidad, filtros frecuentes, claves de unión y ordenamientos habituales.
| Caso | Índice recomendado | Ejemplo |
|---|---|---|
| Búsqueda por ID o código | B-tree simple | cliente_id |
| Filtro por varias columnas | Índice compuesto | cliente_id, fecha |
| Texto o JSON | GIN según el caso | tags, jsonb |
| Tablas muy grandes por fecha | BRIN o particionado | fecha_creacion |
3.4. Mantén VACUUM y ANALYZE bajo control
PostgreSQL usa VACUUM para limpiar filas muertas generadas por actualizaciones y eliminaciones, y ANALYZE para actualizar estadísticas que ayudan al optimizador a elegir buenos planes. El demonio autovacuum puede emitir ANALYZE automáticamente cuando una tabla cambia lo suficiente.
En tablas grandes con mucha escritura, autovacuum suele necesitar ajustes por tabla. Desactivarlo sin un plan es una mala práctica: puede causar crecimiento excesivo, estadísticas obsoletas y riesgo operativo.
3.5. Ajusta memoria sin excederte
En PostgreSQL, shared_buffers define la memoria compartida usada por el servidor para caché de datos, work_mem se usa para operaciones como ordenamientos y hash antes de escribir a disco, y maintenance_work_mem se usa en operaciones de mantenimiento como VACUUM, CREATE INDEX y ALTER TABLE. La documentación oficial advierte que estos parámetros deben entenderse dentro del consumo total de recursos del servidor.
| Parámetro | Función | Riesgo si se configura mal |
|---|---|---|
| shared_buffers | Caché interna de PostgreSQL. | Dejar poca memoria al sistema operativo. |
| work_mem | Memoria por operación de ordenamiento o hash. | Multiplicarse por muchas conexiones y agotar RAM. |
| maintenance_work_mem | Memoria para VACUUM, índices y mantenimiento. | Consumo alto durante tareas administrativas. |
| effective_cache_size | Estimación de caché disponible para el planificador. | Planes poco realistas si se estima mal. |
Cuidado con work_mem: no es memoria global. Puede usarse varias veces por consulta y por conexión. Un valor muy alto puede provocar falta de memoria si hay muchas consultas concurrentes.
3.6. Usa auto_explain para planes lentos
La extensión auto_explain permite registrar automáticamente planes de ejecución de consultas lentas sin ejecutar EXPLAIN manualmente. PostgreSQL la presenta como útil para encontrar consultas no optimizadas en aplicaciones grandes.
4. Optimización en MariaDB
4.1. Activa el slow query log
MariaDB documenta el slow query log como un registro de consultas SQL que tardan mucho tiempo en ejecutarse y advierte que puede contener información sensible si las consultas incluyen contraseñas u otros datos delicados.
Para producción, es mejor guardar estos parámetros en el archivo de configuración correspondiente, proteger el archivo de log y rotarlo adecuadamente.
4.2. Analiza consultas con EXPLAIN
MariaDB documenta EXPLAIN como una forma de mostrar información del optimizador sobre cómo procesará una consulta SELECT, UPDATE o DELETE, incluyendo orden de tablas y métodos de acceso. También indica que el resultado de EXPLAIN puede incluirse en el slow query log.
Presta atención a columnas como type, key, rows y Extra. Si aparece un escaneo de demasiadas filas, si no se usa el índice esperado o si hay ordenamientos temporales innecesarios, debes revisar índices, estadísticas o la forma de la consulta.
4.3. Actualiza estadísticas con ANALYZE TABLE
MariaDB usa estadísticas de índices para orientar al optimizador. La documentación indica que ANALYZE TABLE actualiza estadísticas de distribución de claves que el optimizador utiliza para elegir el mejor plan de ejecución.
4.4. Ajusta InnoDB Buffer Pool
En MariaDB, el InnoDB Buffer Pool es una de las áreas de memoria más importantes para tablas InnoDB, porque almacena páginas de datos e índices. MariaDB mantiene documentación específica para su implementación, configuración y uso.
| Parámetro | Función | Comentario |
|---|---|---|
| innodb_buffer_pool_size | Memoria principal para datos e índices InnoDB. | Debe dimensionarse según RAM y carga real. |
| innodb_log_file_size | Tamaño de logs de redo. | Impacta escrituras y recuperación. |
| innodb_flush_log_at_trx_commit | Durabilidad de commits. | No cambiar sin entender riesgo de pérdida ante falla. |
| max_connections | Máximo de conexiones. | Más conexiones no siempre significan más rendimiento. |
MariaDB también advierte en su documentación de memoria que muchas consultas lentas se corrigen con índices, cambios de esquema o cambios de consulta, no necesariamente ajustando buffers pequeños.
Advertencia: si MariaDB comparte servidor con Apache, PHP, Java, contenedores u otros servicios, no asignes casi toda la RAM al buffer pool. El sistema operativo y las aplicaciones también necesitan memoria.
5. Ajustes comunes para PostgreSQL y MariaDB en Linux
5.1. Usa discos adecuados
Las bases de datos suelen sufrir cuando el almacenamiento no puede sostener escrituras, lecturas aleatorias o sincronizaciones frecuentes. Para producción, conviene usar SSD o NVMe, revisar latencia, IOPS, cola de disco y salud SMART. También es importante separar, cuando el presupuesto lo permita, datos, logs de transacción, backups y sistema operativo.
5.2. Evita swap excesivo
Una base de datos que usa swap de forma constante probablemente está mal dimensionada o tiene demasiadas conexiones/procesos. La memoria debe alcanzar para el motor, el sistema operativo, caché de disco, conexiones y aplicaciones que conviven en el mismo servidor.
5.3. Controla las conexiones
Demasiadas conexiones simultáneas pueden consumir memoria y CPU sin mejorar el rendimiento. En aplicaciones web, suele ser mejor usar pool de conexiones: PgBouncer para PostgreSQL y pool de conexiones desde la aplicación o proxy compatible para MariaDB.
| Problema | Solución recomendada |
|---|---|
| Muchas conexiones inactivas | Pool de conexiones y cierre correcto desde la aplicación. |
| Consultas esperando bloqueos | Transacciones más cortas y revisión de locks. |
| Picos por reportes | Réplicas de lectura o ventanas de ejecución. |
| API saturando la base | Caché, paginación, límites y consultas parametrizadas. |
6. Consultas SQL: errores que destruyen el rendimiento
- Usar SELECT * en tablas grandes cuando solo se necesitan pocas columnas.
- Filtrar columnas indexadas usando funciones que impiden aprovechar el índice.
- Crear índices duplicados o poco selectivos.
- No paginar resultados grandes.
- Hacer reportes pesados sobre la misma base transaccional en horas pico.
- Dejar transacciones abiertas durante mucho tiempo.
- No revisar bloqueos.
- No actualizar estadísticas después de cargas masivas.
- Usar tipos de datos incorrectos para fechas, números o identificadores.
7. Monitoreo mínimo recomendado
PostgreSQL documenta vistas de estadísticas como pg_stat_activity, que muestra información de actividad por proceso del servidor. MariaDB ofrece Performance Schema para observar detalles internos de ejecución y rendimiento. Estas capacidades deben integrarse con herramientas como Prometheus, Grafana, Zabbix, Netdata, Wazuh o sistemas equivalentes.
| Métrica | PostgreSQL | MariaDB |
|---|---|---|
| Consultas lentas | pg_stat_statements, logs, auto_explain. | Slow query log, Performance Schema. |
| Conexiones activas | pg_stat_activity. | SHOW PROCESSLIST, Performance Schema. |
| Bloqueos | pg_locks. | INFORMATION_SCHEMA y Performance Schema. |
| Uso de caché | Buffer hits y estadísticas de tablas. | InnoDB status y buffer pool. |
| Disco | WAL, checkpoints, lecturas/escrituras. | Redo logs, flushes, lecturas/escrituras. |
8. Plan de optimización paso a paso
- Medir: CPU, RAM, disco, conexiones, locks y consultas lentas.
- Identificar: top 10 consultas por tiempo total y por tiempo promedio.
- Analizar: planes con EXPLAIN o EXPLAIN ANALYZE.
- Corregir: índices, consultas, JOINs, paginación y filtros.
- Actualizar estadísticas: VACUUM/ANALYZE en PostgreSQL y ANALYZE TABLE en MariaDB.
- Ajustar memoria: shared_buffers, work_mem, maintenance_work_mem o innodb_buffer_pool_size según motor.
- Controlar conexiones: pool de conexiones y límites razonables.
- Revisar almacenamiento: SSD/NVMe, latencia, espacio, I/O y backups.
- Probar: repetir mediciones antes/después.
- Documentar: fecha, cambio, motivo, resultado y rollback.
9. Configuraciones iniciales orientativas
Los siguientes ejemplos no deben copiarse sin evaluar RAM, carga real, versión del motor y número de conexiones. Sirven como plantilla de partida para documentar ajustes y probarlos en laboratorio.
Ejemplo PostgreSQL
Ejemplo MariaDB
No apliques estos valores en producción sin probar. El tamaño correcto depende de RAM, cantidad de conexiones, carga de lectura/escritura, otros servicios del servidor y comportamiento de la aplicación.
10. Errores frecuentes al optimizar bases de datos
- Cambiar parámetros sin medir antes y después.
- Crear muchos índices sin revisar impacto en escrituras.
- Subir max_connections para ocultar falta de pool.
- Asignar demasiada RAM al motor y dejar sin memoria al sistema operativo.
- No revisar consultas generadas por el ORM.
- Ejecutar reportes pesados en la base transaccional principal.
- No actualizar estadísticas después de cargas masivas.
- No monitorear crecimiento de tablas, índices y logs.
- No probar restauración de backups.
- Usar discos lentos para cargas intensivas.
Preguntas clave
¿Qué debo optimizar primero: servidor o consultas?
Primero mide todo, pero normalmente las consultas e índices generan mejoras más grandes que cambiar parámetros. MariaDB incluso advierte que muchas consultas lentas se corrigen con índices, cambios de esquema o cambios en SELECT antes que con pequeños buffers.
¿PostgreSQL necesita VACUUM manual?
PostgreSQL incluye autovacuum, pero tablas grandes, cargas masivas o patrones intensivos de UPDATE/DELETE pueden necesitar revisión y ajustes. El objetivo es evitar filas muertas acumuladas y estadísticas obsoletas.
¿MariaDB necesita ANALYZE TABLE?
Sí puede ser útil después de cargas grandes o cambios importantes en los datos. ANALYZE TABLE actualiza estadísticas de distribución de claves usadas por el optimizador.
¿Más memoria siempre mejora el rendimiento?
No siempre. Ayuda si la carga se beneficia de caché, pero si el problema es una consulta mal diseñada, un bloqueo o un índice faltante, aumentar memoria solo ocultará parcialmente el problema.
¿Cuándo usar réplicas?
Cuando los reportes, consultas de lectura o procesos externos consumen demasiado en la base principal. Una réplica de lectura puede separar cargas, pero también debe monitorearse el retraso de replicación.
¿SSD o NVMe hacen diferencia?
Sí, especialmente en cargas con muchas lecturas/escrituras aleatorias, índices grandes, WAL/redo logs y bases con alta concurrencia. Aun así, un buen disco no compensa consultas mal diseñadas.
Recomendamos
En resumen
Optimizar PostgreSQL y MariaDB en Linux exige método. Primero mide el servidor, después identifica consultas costosas, revisa planes de ejecución, corrige índices y estadísticas, y finalmente ajusta memoria, conexiones y almacenamiento.
En PostgreSQL, las piezas clave son pg_stat_statements, EXPLAIN ANALYZE, VACUUM, ANALYZE, autovacuum, work_mem y shared_buffers. En MariaDB, las piezas clave son slow query log, EXPLAIN, ANALYZE TABLE, estadísticas de índices e InnoDB Buffer Pool.
La optimización no termina con un cambio de configuración. Debe convertirse en una práctica permanente: monitoreo, revisión de consultas, mantenimiento, backups probados y documentación de cada ajuste.
Conclusión editorial
Una base de datos rápida no nace de un parámetro milagroso. Nace de buenas consultas, buenos índices, estadísticas actualizadas, almacenamiento adecuado y administradores que miden antes de cambiar.

