Solución de problemas de rendimiento

Siga las siguientes instrucciones para solucionar problemas relacionados con IBM Cloud® Databases for PostgreSQL el rendimiento.

Para obtener una descripción general, consulte PostgreSQL rendimiento.

Rendimiento lento de la base de datos

Los síntomas típicos de este problema son los siguientes:

  • Alto uso de E/S (entrada/salida) del disco o de la memoria
  • Consultas lentas

La causa más común es que se estén examinando consultas lentas. Siga los siguientes pasos para determinar si este es el caso:

  1. Enumera las consultas de larga duración:

    select age(now(),query_start), pid, client_addr, state, substring(query,0,80) from pg_stat_activity where state != 'idle' order by 1 desc;
    
  2. Validar bloqueo de consultas:

    select pg_blocking_pids(pid), pid AS blocked_pid, state, query, age(now(),query_start) AS duration from pg_stat_activity where array_length(pg_blocking_pids(pid),1) > 0 order by 1,2;
    
  3. Comprueba el plan de ejecución de la consulta:

    Explain <query>;
    
  4. Comprueba si faltan estadísticas de la base de datos. Utilice la siguiente consulta para validar: Acción > Ejecutar análisis Como alternativa, ejecute el siguiente comando :

    Analyze <tablename>  select relname, n_live_tup, n_dead_tup, last_vacuum,last_autovacuum,last_analyze,last_autoanalyze, analyze_count,autoanalyze_count from pg_stat_all_tables where schemaname='public';
    
  5. Comprueba si falta el índice en la tabla. PostgreSQL proporciona métodos de índice como B-Tree, hash, GiST,SP-GiST, GIN y BRIN. Utilice uno de estos métodos para crear el índice.

  6. Comprueba si la tabla está inflada. Ejecute la siguiente consulta para validar. Acción > Ejecutar vacío

    Como alternativa, utilice la siguiente instrucción:

    SELECT
    relname AS table_name,
    pg_size_pretty(pg_relation_size(c.oid)) AS actual_size,
    pg_size_pretty(
    CASE
    WHEN c.relpages = 0 THEN 0
    ELSE (pg_relation_size(c.oid) - (c.relpages *
    (current_setting('block_size')::numeric - 24))) * 100 / pg_relation_size(c.oid)
    END
    ) AS bloat_percentage, pg_size_pretty(
    CASE
    WHEN c.relpages = 0 THEN 0
    ELSE (pg_relation_size(c.oid) - (c.relpages *
    (current_setting('block_size')::numeric - 24)))
    END
    )AS bloat_size
    FROM pg_class c
    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE relkind = 'r' AND n.nspname = 'public' -- Adjust schema if needed
    ORDER BY bloat_size DESC NULLS LAST;
    
  7. Considere si la base de datos o los objetos se han creado con pg_dump o pg_restore. Utiliza Acción > Actualizar estadísticas para refrescar.

  8. Asegúrese de que se work_mem asigna suficiente si la consulta está completando una operación de ordenación.

  9. Utilice pg_stat las declaraciones para obtener la siguiente información:

    • consultar el tiempo medio de ejecución y el número de llamadas

    • Porcentaje de uso de la CPU por las consultas

    • Porcentaje de uso de memoria por las consultas

pg_stat_activity, pg_stat_bgwriter, y pg_buffercache son herramientas importantes en PostgreSQL para supervisar y comprender el rendimiento de las bases de datos.

Supervisión del despliegue y supervisión de la carga de la base de datos

Databases for PostgreSQL ofrecen una integración con el servicio IBM Cloud Monitoring para supervisar el uso de recursos en su despliegue. Utilice este servicio para supervisar su implementación (disco y memoria) y la carga de su base de datos.

Utilice Cloud Databases los paneles de control para configurar alertas sobre los umbrales de CPU, memoria y IOPS del disco. Muchas de las métricas disponibles, como el uso del disco y las IOPS, son útiles para ayudarte a configurar el autoescalado en tu despliegue. El autoescalado no está habilitado de forma predeterminada, por lo que debe configurarlo manualmente.

Observar las tendencias en su uso y configurar el autoescalado para responder a estas tendencias puede ayudar a aliviar los problemas de rendimiento antes de que sus bases de datos se vuelvan inestables debido al agotamiento de los recursos. Por ejemplo, cambios en la E/S del disco o fallos de la CPU o la memoria que provocan problemas de rendimiento.

IOPS de disco

El número de operaciones de entrada/salida por segundo (IOPS) está limitado por el tipo y el tamaño del volumen de almacenamiento. Los volúmenes de almacenamiento para Databases for PostgreSQL implementaciones se aprovisionan en volúmenes Block Storage de resistencia en el nivel de 10 IOPS por GB.

Si la carga operativa satura o supera el límite de IOPS, las peticiones y operaciones de la base de datos se retrasan hasta que el subsistema de almacenamiento puede ponerse al día. Los periodos prolongados de gran carga pueden provocar que su implantación no sea capaz de procesar las consultas y deje de estar disponible. Puede aumentar el número de IOPS disponibles para su implantación aumentando el tamaño de los discos. Por ejemplo, para 10 IOPS por nivel de GB, puede aumentar las IOPS aumentando el tamaño del volumen.

Los periodos prolongados de utilización del disco, incluso del 40-50 %, pueden tener un impacto negativo significativo en el rendimiento de la base de datos. Asigne al menos 100 GB de disco (1.000 IOPS) para entornos de producción. IOPS = 10 × GB asignados (por ejemplo, 100 GB = 1000 IOPS)

Uso de memoria

La memoria es la forma más rápida y eficiente de acceder y procesar datos. Por este motivo, una base de datos casi siempre funciona más rápido utilizando la memoria en lugar de leer los datos del disco. Hay otras métricas que hay que tener en cuenta y considerar, como las visitas a la caché, los bloques leídos y los bloques visitados. El simple hecho de ver un uso de memoria del 100 % no es motivo de preocupación en sí mismo. Si se agota la memoria y se utilizan páginas de intercambio, el rendimiento puede verse significativamente reducido.

Puede establecer la cantidad de memoria dedicada al conjunto de búferes compartidos de la base de datos ajustando shared_buffers en la configuración de Databases for PostgreSQL. El valor máximo recomendado es el 25% de la memoria total de la implantación. Asignar demasiada memoria a la reserva de búferes compartidos puede privar al sistema de memoria para otros fines, puede entorpecer el rendimiento o incluso desactivar la base de datos.

Supervisión de la carga de la base de datos

Tienes dos opciones para comprobar la carga de la base de datos:

Opción 1. Comprueba si hay consultas de larga duración utilizando IBM Cloud Logs ( ICL ):

Para obtener más información, consulte ¿Cómo puedo realizar un seguimiento del historial de consultas?

Puede utilizar la siguiente consulta de DataPrime ejemplo en IBM Cloud Logs.

  1. Después de cargar IBM Cloud los registros, cambie a la </>DataPrime pestaña. No cambies nada en la barra de búsqueda </>Lucene.
  2. En la </>DataPrime pestaña, ejecute la siguiente búsqueda para encontrar SQL que se ejecuta durante más de 1000 milisegundos. También puede pegarlo en la búsqueda de la </>DataPrime pestaña.
{

source logs|filter message.attr.durationMillis>=1000

}

Opción 2. Habilitar el log_min_duration_statement

El uso de log_min_duration_statement especifica que se registran las instrucciones que tardan más del número de milisegundos especificado. Para obtener más información, consulte log_min_duration_statement.

También puede instalar la extensión pg_stat_statements:

CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Esta extensión le permite consultar las estadísticas para encontrar ejemplos de consultas que tardan mucho tiempo en ejecutarse. A continuación, puede aislar los problemas y considerar un patrón de consulta diferente, índices nuevos o modificados, un diseño de tabla diferente u otras estrategias para mejorar el rendimiento.

Consulta 1: Identificar consultas que consumen mucho tiempo

Puede detectar consultas que consumen mucho tiempo ejecutando la siguiente instrucción:

SELECT username, database, queryid, query_preview, calls, total_exec_time, pct_exec_time, ROUND(SUM(pct_exec_time) OVER (ORDER BY total_exec_time DESC)) AS cum_pct_exec_time, avg_exec_time FROM ( SELECT pu.usename AS username, pd.datname AS database, pss.queryid, LEFT(pss.query, 50) AS query_preview, pss.calls, ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time, ROUND((100.0 * pss.total_exec_time / SUM(pss.total_exec_time) OVER ())::numeric, 2) AS pct_exec_time, ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time FROM pg_stat_statements pss JOIN pg_user pu ON pss.userid = pu.usesysid JOIN pg_database pd ON pss.dbid = pd.oid ) AS subquery ORDER BY total_exec_time DESC LIMIT 25;

Esta instrucción produce el siguiente resultado:

Resultado de una consulta que requiere mucho tiempo
nombre de usuario Base de datos queryid vista previa de consulta calls tiempo_total_de_ejecución tiempo_ejecución_pct porcentaje_de_tiempo_de_ejecución tiempo_de_ejecución_promedio
ibm postgres 50685 38286.580 19.52 20 0.755
ibm postgres 280111 28477.951 14.52 34 0.102
ibm postgres 18 14568.978 7.43 41 809.388
ibm postgres 18 12103.904 6.17 48 672.439
ibm ibmclouddb 37552 7799.984 3.98 52 0.208
(5 filas)

La consulta realiza un seguimiento de las estadísticas de ejecución de las sentencias SQL y proporciona la siguiente información:

  • Muestra las 25 consultas que más tiempo tardaron en ejecutarse en total
  • Muestra quién ejecutó la consulta, en qué base de datos y una vista previa de la consulta
  • Muestra la frecuencia con la que se ejecutó cada consulta y el tiempo medio que tardó en completarse
  • Calcula el porcentaje del tiempo total de la base de datos que ha utilizado cada consulta
  • Proporciona un total acumulado del tiempo de uso de la base de datos

Consulta 2: Identificar consultas ejecutadas con frecuencia

Puede detectar las consultas que se ejecutan con frecuencia ejecutando la siguiente instrucción:

SELECT
   username,
   database,
   queryid,
   query_preview,
   calls,
   pct_calls,
   ROUND(SUM(pct_calls) OVER (ORDER BY calls DESC)) AS cum_pct_calls,
   total_exec_time,
   avg_exec_time
FROM (
   SELECT
      pu.usename AS username,
      pd.datname AS database,
      pss.queryid,
      LEFT(pss.query, 50) AS query_preview,
      pss.calls,
      ROUND(100.0 * pss.calls / SUM(pss.calls) OVER (), 2) AS pct_calls,
      ROUND(pss.total_exec_time::numeric, 3) AS total_exec_time,
      ROUND(pss.mean_exec_time::numeric, 3) AS avg_exec_time
   FROM
      pg_stat_statements pss
      JOIN pg_user pu ON pss.userid = pu.usesysid
      JOIN pg_database pd ON pss.dbid = pd.oid
) AS subquery
ORDER BY
   calls DESC
LIMIT 25;

Esta instrucción produce el siguiente resultado:

Resultado de una consulta ejecutada con frecuencia
nombre de usuario Base de datos queryid vista previa de consulta llamadas pct_llamadas porcentaje de llamadas tiempo_total_de_ejecución tiempo_de_ejecución_promedio
ibm postgres 80285 23.84 24 16095.420 0.200
ibm postgres 36832 10.94 35 548.787 0.015
ibm postgres 20626 6.12 41 741.755 0.036
ibm postgres 14702 4.36 45 23982.252 1.631
ibm postgres 12436 3.69 49 1750.426 0.141

La consulta proporciona la siguiente información:

  • Muestra las 25 consultas que se ejecutaron con más frecuencia
  • Muestra quién ejecutó la consulta, en qué base de datos y una vista previa de la consulta
  • Muestra cuántas veces se ejecutó cada consulta y cuánto tiempo tardó en total y de media
  • Calcula el porcentaje de todas las llamadas de consulta que representa cada consulta
  • Proporciona un total acumulado de llamadas de consulta

Obtener el rendimiento actual de todas las consultas

  1. Para obtener el rendimiento actual en todas las consultas, ejecute la siguiente instrucción:

    select now() as t1,sum(total_exec_time) as et1, sum(calls) as c1 from pg_stat_statements
    

    Esto produce el siguiente resultado:

    Resultado de la ejecución de todas las consultas actuales.
    t1 et1 c1
    30 de septiembre de 2025 08:15:43.898157 +00 104109.55454499979 336889
    (1 row)
  2. A continuación, espere 10 segundos y ejecute la siguiente instrucción:

    select now() as t2,sum(total_exec_time) as et2, sum(calls) as c2 from pg_stat_statements
    

    Esto produce el siguiente resultado:

    Resultado de la instrucción select now()
    t2 et2 c2
    30 de septiembre de 2025 08:16:18.943609 +00 104113.70054399982 336896
    (1 row)
  3. Calcula las consultas por segundo:

    Queries per second = (c2-c1)/(t2-t1) and average query performance = (et2-et1)/(c2-c1)
    

Las 10 consultas que más tiempo consumen

Para obtener las 10 consultas que más tiempo consumen:

SELECT query, calls, total_exec_time/calls as avg_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

Esto produce el siguiente resultado:

| Consulta | llamadas | tiempo_promedio |   | | -------------- | -------------- | -------------- | | <privilegios insuficientes> | 14706 |   1.6311896077791408 | | <privilegios insuficientes> | 80305 |   0.2004813740987463 | | <privilegios insuficientes> |     6 |   800.7297508333332 | | <privilegios insuficientes> |     6 |   721.1415835000001 | | <privilegios insuficientes> | 10316 |   0.3907427791779766 | | <privilegios insuficientes> | 10316 | 0.35429842613416024 | | <privilegios insuficientes> | 10316 |   0.3184477990500202 | | <privilegios insuficientes> | 10316 |   0.2285179489143081 | | <privilegios insuficientes> | 12439 |   0.1407493980223488 | | <privilegios insuficientes> | 10316 |   0.1605010507948812 | | (10 filas) | | |

Otras medidas que puede tomar para mejorar el rendimiento

También puede considerar las siguientes acciones para solucionar problemas de rendimiento:

  • Optimizar las consultas lentas

    • Ejecute EXPLAIN (ANALYZE, BUFFERS) en consultas lentas. Esto muestra cómo la base de datos ejecuta la consulta y dónde es lenta. Por ejemplo:
    EXPLAIN (ANALYZE, BUFFERS)
    SELECT * FROM student WHERE student_id = 12345;
    
    • Busque:

      • Consultas que utilizan mucha memoria o espacio en disco

      • Añadir IBM Cloud recursos según sea necesario

      • Amplíe el disco/memoria para obtener mayores IOPS y memoria

  • Los índices que faltan o son ineficaces son una causa habitual de consultas lentas. Utilice EXPLAIN para identificar los escaneos secuenciales y considere la posibilidad de añadir índices.

  • Ejecute VACUUM para ayudar con el análisis del estado de la base de datos.

  • Considere la posibilidad de utilizar la agrupación de conexiones para gestionar más conexiones. Databases for PostgreSQL establece en 115 el número máximo de conexiones a su base de datos Databases for PostgreSQL. 15 conexiones están reservadas para el superusuario para mantener el estado y la integridad de tu base de datos, y 100 conexiones están disponibles para ti y tus aplicaciones. Una vez alcanzado el límite de conexiones, cualquier intento de iniciar una nueva conexión produce un error. Para evitar saturar despliegue con conexiones, utilice agrupación de conexiones o reduzca el despliegue y aumente el límite de conexiones. Para obtener más información, consulte Administración del PostgreSQL agrupamiento de conexiones.

  • Comprueba si hay alguna receta que esté realizando copias de seguridad y cargando datos por lotes, por ejemplo: Las copias de seguridad automáticas se realizan a diario y se conservan durante un periodo de retención de 30 días. Si una copia de seguridad se ha quedado atascada, puede consultar la sección Copias de seguridad disponibles e identificar la copia de seguridad atascada en la página de la interfaz de usuario de la nube de la instancia de la base de datos.

  • Comprueba tus IBM Cloud notificaciones para ver si hay algún mantenimiento. Por ejemplo, la aplicación de parches a bases de datos.

  • Si cree que se trata de un problema de la plataforma, como por ejemplo un mantenimiento, póngase en contacto con IBM el servicio de asistencia técnica indicando el número de referencia de la base de datos.