--- title: "Benchmark de PostgreSQL y MySQL con pgbench y mysqlslap" description: "Mide el rendimiento de PostgreSQL con pgbench y de MySQL con mysqlslap en Ubuntu 24.04: TPS, latencia, concurrencia, consultas propias y ajustes." category: "Rendimiento y Benchmarking" language: es source: https://cubepath.com/es/docs/rendimiento-y-benchmarking/benchmarking-de-base-de-datos-con-pgbench-y-mysqlslap updated: 2026-09-25 --- # Benchmark de PostgreSQL y MySQL con pgbench y mysqlslap pgbench y mysqlslap son las herramientas de benchmarking que vienen incluidas con PostgreSQL y MySQL respectivamente. pgbench ejecuta una carga transaccional parecida a TPC-B y mide transacciones por segundo (TPS) y latencia; mysqlslap lanza consultas desde varios clientes concurrentes y mide cuánto tardan en completarse. En este tutorial usarás ambas en Ubuntu 24.04 para obtener una línea base, probar distintos niveles de concurrencia, ejecutar tus propias consultas y comprobar el efecto de un cambio de configuración. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 2 GB de RAM. - Un usuario no root con privilegios `sudo`. - Unos 5 GB libres en disco. - PostgreSQL 16 para la primera parte y MySQL 8.0 para la segunda. Puedes seguir solo la parte del motor que uses. > Importante: no lances estas pruebas contra una base de datos en producción. Generan carga intensa y pgbench crea y modifica sus propias tablas. Usa un servidor de pruebas o una base de datos dedicada. ## Paso 1: Instalar PostgreSQL y comprobar pgbench Instala PostgreSQL desde los repositorios de Ubuntu. `pgbench` se instala junto con él: ```bash sudo apt update sudo apt install postgresql ``` Comprueba que el servicio está activo y que pgbench está disponible: ```bash systemctl status postgresql --no-pager pgbench --version ``` ```output pgbench (PostgreSQL) 16.10 (Ubuntu 16.10-0ubuntu0.24.04.1) ``` ## Paso 2: Inicializar la base de datos de prueba pgbench necesita sus propias tablas (`pgbench_accounts`, `pgbench_branches`, `pgbench_tellers` y `pgbench_history`). Crea una base de datos dedicada como usuario `postgres`: ```bash sudo -u postgres createdb pgbench ``` Llena las tablas con `-i` (inicializar). El factor de escala `-s` fija el volumen: cada unidad son 100.000 filas en `pgbench_accounts`, unos 15 MB. Con `-s 50` obtienes 5 millones de filas y unos 750 MB: ```bash sudo -u postgres pgbench -i -s 50 pgbench ``` ```output dropping old tables... creating tables... generating data (client-side)... 5000000 of 5000000 tuples (100%) done (elapsed 6.12 s, remaining 0.00 s) vacuuming... creating primary keys... done in 8.94 s (drop tables 0.00 s, create tables 0.01 s, client-side generate 6.25 s, vacuum 0.84 s, primary keys 1.84 s). ``` Comprueba el tamaño de la base de datos: ```bash sudo -u postgres psql -d pgbench -c "SELECT pg_size_pretty(pg_database_size('pgbench'));" ``` > Consejo: si quieres medir el disco y no solo la memoria, elige un factor de escala cuyo tamaño supere la RAM del servidor. Si la base de datos cabe en `shared_buffers` y en la caché del sistema, estarás midiendo sobre todo CPU. ## Paso 3: Ejecutar el benchmark estándar de pgbench Lanza la prueba por defecto durante 60 segundos con 10 clientes y 2 hilos de pgbench, mostrando el progreso cada 10 segundos: ```bash sudo -u postgres pgbench -c 10 -j 2 -T 60 -P 10 pgbench ``` - `-c`: clientes concurrentes, es decir, conexiones abiertas a la vez. - `-j`: hilos del propio pgbench que reparten esos clientes. Usa como máximo el número de vCPU. - `-T`: duración en segundos. - `-P`: intervalo del informe de progreso. ```output progress: 10.0 s, 1482.3 tps, lat 6.738 ms stddev 2.911, 0 failed progress: 20.0 s, 1510.8 tps, lat 6.617 ms stddev 2.640, 0 failed ... transaction type: scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 maximum number of tries: 1 duration: 60 s number of transactions actually processed: 89915 number of failed transactions: 0 (0.000%) latency average = 6.672 ms latency stddev = 2.781 ms initial connection time = 21.305 ms tps = 1498.712305 (without initial connection time) ``` Las cifras que debes anotar son `tps` (más alto es mejor) y `latency average` (más bajo es mejor). Si la desviación típica es grande comparada con la media, hay picos de latencia, normalmente por esperas de disco o bloqueos. La transacción por defecto hace tres `UPDATE`, un `SELECT` y un `INSERT`, así que mide sobre todo escritura. Para una carga de solo lectura usa `-S`: ```bash sudo -u postgres pgbench -S -c 10 -j 2 -T 60 pgbench ``` ## Paso 4: Medir cómo escala con la concurrencia El número de clientes a partir del cual los TPS dejan de crecer indica la concurrencia útil del servidor. Repite la prueba con distintos valores: ```bash for c in 1 4 8 16 32 64; do printf 'clientes=%s ' "$c" sudo -u postgres pgbench -c "$c" -j 2 -T 30 pgbench 2>/dev/null | grep '^tps' done ``` ```output clientes=1 tps = 412.550812 (without initial connection time) clientes=4 tps = 1204.117320 (without initial connection time) clientes=8 tps = 1471.908156 (without initial connection time) clientes=16 tps = 1552.360479 (without initial connection time) clientes=32 tps = 1538.902214 (without initial connection time) clientes=64 tps = 1490.221730 (without initial connection time) ``` En este ejemplo el rendimiento se estanca en torno a 16 clientes. Por encima solo aumenta la latencia, algo a tener en cuenta al dimensionar el pool de conexiones de la aplicación. PostgreSQL admite 100 conexiones por defecto (`max_connections`), así que no pases de ese valor sin ajustarlo. ## Paso 5: Probar tus propias consultas con pgbench pgbench puede ejecutar un script SQL propio con `-f`. Las variables se definen con `\set` y se usan como `:nombre`; `:scale` contiene el factor de escala. Crea un script que simula lecturas por clave primaria: ```bash nano ~/select-account.sql ``` ```sql \set aid random(1, 100000 * :scale) SELECT abalance FROM pgbench_accounts WHERE aid = :aid; ``` pgbench se ejecuta como `postgres`, que no puede leer tu directorio personal, así que pásale el script por una tubería: ```bash cat ~/select-account.sql | sudo -u postgres pgbench -f /dev/stdin -c 16 -j 2 -T 30 -M prepared pgbench ``` `-M prepared` usa sentencias preparadas, como hacen la mayoría de controladores de aplicación, y suele dar más TPS que el modo `simple` por defecto. Para probar consultas de tu aplicación, crea sus tablas en esta base de datos y cambia el `SELECT` por las consultas reales. ## Paso 6: Comparar antes y después de un ajuste El uso más valioso de pgbench es cuantificar un cambio. Guarda primero una línea base: ```bash sudo -u postgres pgbench -c 16 -j 2 -T 120 pgbench | tee ~/pgbench-antes.txt ``` Como ejemplo, sube `shared_buffers` desde los 128 MB por defecto a un 25 % de la RAM. En un servidor de 4 GB, edita el archivo de configuración: ```bash sudo nano /etc/postgresql/16/main/postgresql.conf ``` Busca la línea `shared_buffers` y déjala así: ```ini shared_buffers = 1GB ``` `shared_buffers` solo se aplica al reiniciar el servicio: ```bash sudo systemctl restart postgresql sudo -u postgres psql -c "SHOW shared_buffers;" ``` Repite exactamente la misma prueba y compara: ```bash sudo -u postgres pgbench -c 16 -j 2 -T 120 pgbench | tee ~/pgbench-despues.txt grep -H -E '^tps|latency average' ~/pgbench-antes.txt ~/pgbench-despues.txt ``` Ejecuta cada prueba al menos dos o tres veces. Diferencias de un 2-3 % entre ejecuciones son ruido; no saques conclusiones de ellas. ## Paso 7: Instalar MySQL y comprobar mysqlslap Pasa ahora a MySQL. Instala el servidor, que incluye el cliente y mysqlslap: ```bash sudo apt install mysql-server mysqlslap --version ``` ```output mysqlslap Ver 8.0.43-0ubuntu0.24.04.1 for Linux on x86_64 ((Ubuntu)) ``` En Ubuntu, el usuario `root` de MySQL se autentica por socket Unix, así que puedes ejecutar mysqlslap con `sudo` sin contraseña. ## Paso 8: Ejecutar una carga automática con mysqlslap mysqlslap puede generar tablas y consultas por sí mismo. Esta orden crea una tabla temporal, lanza una carga mixta de lecturas y escrituras con 10, 50 y 100 clientes, repite cada nivel tres veces y borra el esquema al terminar: ```bash sudo mysqlslap --auto-generate-sql \ --auto-generate-sql-load-type=mixed \ --auto-generate-sql-add-autoincrement \ --number-int-cols=4 --number-char-cols=4 \ --concurrency=10,50,100 --iterations=3 \ --number-of-queries=20000 --engine=innodb ``` ```output Benchmark Running for engine innodb Average number of seconds to run all queries: 1.842 seconds Minimum number of seconds to run all queries: 1.790 seconds Maximum number of seconds to run all queries: 1.911 seconds Number of clients running queries: 10 Average number of queries per client: 2000 Benchmark Running for engine innodb Average number of seconds to run all queries: 1.503 seconds ... Number of clients running queries: 50 Average number of queries per client: 400 ``` El total de consultas se reparte entre los clientes, así que cada bloque ejecuta el mismo trabajo. Si el tiempo medio baja al subir la concurrencia, el servidor aprovecha el paralelismo; si sube, está saturado. Otros tipos de carga para `--auto-generate-sql-load-type` son `read`, `write`, `key` y `update`. ## Paso 9: Probar tus propias consultas con mysqlslap Las consultas generadas son sintéticas. Para algo más representativo, define tu propio esquema y tus consultas. Crea el archivo de creación de datos: ```bash nano ~/slap-create.sql ``` ```sql CREATE TABLE orders (id INT AUTO_INCREMENT PRIMARY KEY, customer_id INT NOT NULL, total DECIMAL(10,2) NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_customer (customer_id)); INSERT INTO orders (customer_id, total) VALUES (1, 19.90), (2, 45.00), (3, 12.50), (1, 99.99), (4, 7.25); INSERT INTO orders (customer_id, total) SELECT FLOOR(1 + RAND() * 1000), ROUND(RAND() * 200, 2) FROM orders a, orders b, orders c, orders d; ``` Crea el archivo con las consultas que se lanzarán en cada iteración: ```bash nano ~/slap-query.sql ``` ```sql SELECT * FROM orders WHERE customer_id = 42; SELECT customer_id, SUM(total) FROM orders GROUP BY customer_id ORDER BY 2 DESC LIMIT 10; INSERT INTO orders (customer_id, total) VALUES (42, 25.00); ``` Ejecuta la prueba. `--delimiter` indica cómo separar las sentencias dentro de los archivos: ```bash sudo mysqlslap --create-schema=slaptest \ --create=$HOME/slap-create.sql --query=$HOME/slap-query.sql \ --delimiter=";" --concurrency=20 --iterations=5 ``` mysqlslap crea el esquema `slaptest`, ejecuta las consultas desde 20 clientes cinco veces y lo elimina al final. Si quitas el índice `idx_customer` del `CREATE TABLE` y repites, verás cómo cambia el tiempo medio: es una forma rápida de medir el impacto de un índice. > Nota: mysqlslap mide el tiempo total de un lote de consultas, no TPS ni percentiles de latencia. Para una carga OLTP comparable a pgbench en MySQL, usa `sysbench oltp_read_write`. ## Paso 10: Limpiar Elimina la base de datos de pgbench cuando termines: ```bash sudo -u postgres dropdb pgbench ``` mysqlslap ya elimina sus esquemas al terminar. Comprueba que no queda ninguno: ```bash sudo mysql -e "SHOW DATABASES;" ``` ## Solución de problemas - **`pgbench: error: connection to server on socket ... failed: FATAL: role "your_user" does not exist`**: estás ejecutando pgbench con tu usuario. Usa `sudo -u postgres` como en los ejemplos. - **`FATAL: sorry, too many clients already`**: `-c` supera `max_connections`. Reduce el número de clientes o sube el límite en `postgresql.conf`. - **`mysqlslap: Error when connecting to server: 1045 Access denied for user 'your_user'@'localhost'`**: ejecuta mysqlslap con `sudo` para autenticarte como `root` por socket, o indica un usuario con `-u` y `-p`. - **`Too many connections`** en mysqlslap: la concurrencia supera `max_connections` de MySQL (151 por defecto). ## Conclusión Con pgbench has obtenido TPS y latencia de PostgreSQL, has visto hasta dónde escala con la concurrencia y has medido el efecto de un ajuste de `shared_buffers`. Con mysqlslap has probado MySQL con carga automática y con tus propias consultas. Como siguientes pasos, puedes medir el disco que hay debajo con `fio`, ejecutar `sysbench oltp_read_write` para una comparación OLTP más completa en MySQL, o revisar las consultas lentas reales con `pg_stat_statements`.