DALL·E 2024 03 27 13.06.58 Imagine a 1024x1024 pixels illustration that visualizes the concept of understanding the PostgreSQL query planner. The image should depict a stylized

Entendiendo el Planificador de PostgreSQL

Cuando envías una consulta a PostgreSQL, normalmente pasará por varias etapas de procesamiento y te devolverá los resultados al final.

Estas etapas son:

  • Parseo
  • Análisis
  • Reescribir
  • Planificar
  • Ejecutar

En el post de hoy nos centraremos únicamente en la etapa de «planificar». En concreto, exploraremos el módulo del planificador de PostgreSQL para entender su funcionamiento interno para manejar un simple escaneo secuencial.

NOTA: Mi intención es hacer otro post hablando sobre el resto de etapas, si existe cuando estés leyendo esto estará Linkado aquí. Si no existe, hazme presión social en alguna de mis RRSS.

Mini-introducción

El objetivo principal de la etapa de planificación, o módulo del planificador, es identificar la ruta más rápida a partir de una lista de rutas disponibles y crear un «plan» a partir de ella, que posteriormente será ejecutado en la etapa siguiente.

El objetivo parece sencillo, pero el identificar la vía más rápida es lo que hace que el planificador sea complejo.

¿Dónde comienza todo?

La función exec_simple_query() de postgres.c es el punto de partida de todo el proceso de consulta.

En cualquier caso, como ya hemos comentado, nos centraremos en lo que sucede después de que llega a pg_plan_query().

Hay varias funciones y funcionalidades que se están realizando detrás de bambalinas, algunas de ellas son:

• Identificar sub-consultas, tablas particionadas, tablas externas, uniones, etc.

• Estimar los tamaños de todas las tablas que intervienen en la consulta, con ayuda del método de acceso a tablas.

• Identificar todas las posibles rutas para completar la consulta: escaneo secuencial, escaneo de índices, escaneo de TID, trabajador paralelo, entre otros.

A partir de estas posibles rutas, el planificador seleccionará la de menor costo y la usará como guía para crear un plan de ejecución.

En esta imagen cortesía de Cary Huang se pueden ver (muy simplificado) las fases y funciones internas por las que pasan una query sencilla de SELECT.

image 11

set_base_rel_sizes()

Es el primer proceso que interviene. Esta función estima el tamaño de todas las relaciones (tablas, vistas, índices, etc.) involucradas en la consulta.

Es importante estimar el número esperado de filas (tuplas) y columnas, y para ello se utiliza el «método de acceso a heap», que tiene acceso al «administrador de búferes» y al «administrador de almacenamiento».

set_base_rel_pathlist()

Luego, el proceso set_base_rel_pathlist() se encarga de escanear las posibles rutas que se utilizarán para el set de consultas.

Actualmente, el proceso proporciona cuatro rutas de escaneo a elegir:

• Escaneo secuencial
• Escaneo secuencial parcial
• Escaneo de índice
• Escaneo de TID

Cada ruta tiene un costo estimado dependiendo del número de tuplas o páginas y del coste por página/tupla. Todas ellas medidas en una escala arbitraria.

# - Constantes de costos del planificador -

seq_page_costo = 1,0 
random_page_costo = 4,0 
cpu_tuple_costo = 0.01 
cpu_index_tuple_costo = 0.005 
cpu_operator_costo = 0.0025 
parallel_setup_costo = 1000.0 
parallel_tuple_costo = 0.1 

Básicamente, podría influir en la decisión del planificador a la hora de elegir la ruta más idónea para realizar un plan.

Por ejemplo, si prefiere que el planificador utilice el escaneo paralelo más a menudo, podríamos considerar hacer el coste por tupla de escaneo paralelo más barato, haciendo «parallel_tuple_cost» más pequeño. Por ejemplo, 0.001.

El «add_path» es llamado para añadir una ruta a una lista de rutas potenciales, pero debemos tener en cuenta que el mecanismo de construcción de rutas del planificador tiene un mecanismo de expulsión.

Esto significa que si tenemos la intención de añadir una ruta que es significativamente mejor que el resto de las rutas ya añadidas, es posible que elimine todas las rutas existentes mientras acepta la nueva.

Del mismo modo, si el camino a añadir es significativamente peor, no se añadiría en absoluto. Se llama a «add_partial_path» si el planificador considera segura la exploración secuencial paralela.

Este tipo de escaneo secuencial es «parcial» porque necesita ser recogido y agregado para formar los resultados finales, resultando en costes extra allí, por lo que el paralelismo puede o no ser siempre ideal.

generate_gather_paths

Este proceso se utiliza cuando ya hay rutas parciales agregadas, normalmente como subruta del escaneo secuencial.

Este genera una nueva posibilidad de escaneo paralelo llamada «recolección», que tiene una subruta secuencial.

Los costos de cada ruta y el costo de recopilación de datos se tienen en cuenta en este proceso.

get_cheapest_fractional_path y create_plan

Una vez que se han agregado todas las posibles rutas, se usa esta función para elegir la ruta más barata y luego esta ruta se alimenta a «create_plan», donde la ruta (y subrutas, si las hubiera) se crea de manera recursiva y se formula en una estructura de plan final que se puede ejecutar.

Examinar el plan

Se utiliza la función EXPLAIN ANALYZE para examinar el mejor plan elegido por el planificador y sus detalles de costo.

Conclusión

El planificador de PostgreSQL es complejo, pero esperamos que este artículo pueda ayudarle a entender algunos de sus principios de trabajo básicos. Esto podría ser útil si se quiere mejorar algunos aspectos del planificador o agregar nuevas opciones de rutas.

Únete a la lista de emails para no perderte nada

No tengo ningún producto, publicidad, ni nada que venderte. De hecho, aún no tengo nada que hacer con estos emails. Pero si te interesa estar en contacto o no perderte las próximas actualizaciones en el futuro… Ya sabes 😉

    ¿Quieres trabajar con nosotros?

    Ya sea que necesites mejorar el rendimiento de consultas existentes, planificar y ejecutar migraciones de datos críticas, diseñar bases de datos desde cero o mantener un entorno de base de datos estable, estamos aquí para ayudarte.

    Trabajamos con una amplia variedad de sistemas de gestión de bases de datos (DBMS) y estamos comprometidos en proporcionar soluciones adaptadas a tus necesidades específicas. Puedes consultar nuestra lista completa de servicios aquí.

    Confía en nosotros para optimizar tus bases de datos y liberar tiempo y recursos para que puedas concentrarte en lo que realmente importa: hacer crecer tu negocio.

    ¡Contáctanos hoy mismo y descubre cómo podemos ayudarte a lograr un rendimiento óptimo en tu entorno de bases de datos!


    Comentarios

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *