La extensión pg_hint_plan le permite anular el planificador basado en costos de PostgreSQL mediante hints integrados en comentarios SQL, como /*+ SeqScan(orders) */. Utilícela cuando el planificador seleccione un plan de consulta subóptimo que no pueda corregirse únicamente con actualizaciones de estadísticas o cambios en los índices.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
Una instancia de RDS PostgreSQL 10 o posterior
Una cuenta con privilegios en la instancia. Para crear una, consulte Create an account
Para RDS PostgreSQL 17, la versión menor del motor debe ser 20241030 o posterior. Si no puede crear la extensión, upgrade the minor engine version primero.
Funcionamiento
PostgreSQL utiliza un optimizador basado en costos que estima el costo de cada plan de consulta posible y selecciona aquel con el menor costo. Dado que el optimizador trabaja a partir de estadísticas y no con base en su conocimiento de los datos, en ocasiones pasa por alto patrones inherentes a la información y elige un plan subóptimo.
pg_hint_plan lee hints especiales desde comentarios SQL y los transmite al planificador antes de la optimización. Esto le permite especificar el método de escaneo, el método de unión, el orden de unión y otros comportamientos del planificador para una consulta específica, sin necesidad de modificar los datos ni las estadísticas.
Instalación de la extensión
Instalación desde la consola
Vaya a la lista de instancias de RDS, seleccione una región y haga clic en el ID de la instancia.
En el panel de navegación izquierdo, haga clic en Plug-ins.
-
En la página Extension Management, vaya a la pestaña Uninstalled Extensions, busque pg_hint_plan y haga clic en Install dentro de la columna Actions.

En el cuadro de diálogo, seleccione la base de datos destino y una cuenta con privilegios; después, haga clic en OK.
La extensión se considera instalada cuando el estado de la instancia cambia de Maintaining Instance a Running.
Instalación mediante SQL
-
Set the instance parameters para agregar
pg_hint_planal Running Value deshared_preload_libraries. Por ejemplo:'pg_stat_statements,auto_explain,pg_hint_plan' -
Con una cuenta con privilegios, connect to the database donde desee instalar la extensión y ejecute:
CREATE EXTENSION pg_hint_plan;
Actualización o desinstalación de la extensión
En la página Extension Management, haga clic en la pestaña Installed Extensions:
Para actualizar: haga clic en Upgrade dentro de la columna Actions. Si no aparece el botón Upgrade, significa que la extensión ya se encuentra en su versión más reciente.
Para desinstalar: haga clic en Uninstall dentro de la columna Actions.
Para desinstalar mediante SQL:
DROP EXTENSION pg_hint_plan;
Escritura de hints en comentarios
Los hints se colocan en un comentario de bloque que comienza con /*+ y termina con */, justo antes de la instrucción SQL. Cada hint consta de un nombre y sus parámetros entre paréntesis; los parámetros se separan con espacios.
Uso de alias de tabla en los hints
Si una consulta emplea un alias de tabla, el hint debe hacer referencia al alias y no al nombre original de la tabla. Usar el nombre original provoca que el hint se ignore silenciosamente.
Hint con alias (efectivo):
Uso de la tabla de hints para SQL no editable
Cuando no sea posible modificar directamente la instrucción SQL, almacene los hints en la tabla hint_plan.hints. Los hints almacenados en esta tabla tienen prioridad sobre los hints en comentarios en línea.
De forma predeterminada, el usuario que crea la extensión pg_hint_plan cuenta con permisos sobre la tabla hint_plan.hints.
La tabla incluye las siguientes columnas:
|
Columna |
Descripción |
|
|
Identificador único de fila, generado automáticamente. |
|
|
Patrón que coincide con la instrucción SQL objetivo. Reemplace todas las constantes con |
|
|
Nombre de la aplicación para limitar el alcance del hint. Déjelo en blanco para aplicarlo a todas las aplicaciones. |
|
|
Contenido del hint, sin las marcas de comentario circundantes |
Habilitación de la tabla de hints
SET pg_hint_plan.enable_hint_table = on;
Gestión de hints en la tabla
Inserte un hint:
INSERT INTO hint_plan.hints (norm_query_string, application_name, hints)
VALUES (
'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
'',
'SeqScan(t1)'
);
Actualice un hint:
UPDATE hint_plan.hints
SET hints = 'IndexScan(t1)'
WHERE id = 1;
Elimine un hint:
DELETE FROM hint_plan.hints
WHERE id = 1;
Tipos de hints
pg_hint_plan admite seis categorías de hints.
Hints de método de escaneo
Fuerzan o prohíben un método de escaneo específico sobre una tabla. Si la tabla tiene un alias en la consulta, utilice dicho alias en el hint.
Válido en: tablas ordinarias, tablas heredadas, tablas sin registro (unlogged), tablas temporales y tablas del sistema.
No válido en: tablas externas, funciones de tabla, expresiones de valor constante, expresiones universales, vistas y subconsultas.
Ejemplo: forzar un escaneo secuencial en t1 y un escaneo por índice en t2:
Hints de método de unión
Fuerzan o prohíben un método de unión específico entre tablas.
Válido en: tablas ordinarias, tablas heredadas, tablas sin registro (unlogged), tablas temporales, tablas externas, tablas del sistema, funciones de tabla, expresiones de valor constante y expresiones universales.
No válido en: vistas y subconsultas.
Hints de orden de unión
Controlan el orden en que se unen las tablas. Existen dos formas disponibles:
-
Especificar solo el orden de unión (el planificador decide la dirección):
/*+ Leading(t1 t2 t3) */ SELECT * FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key) JOIN table3 t3 ON (t2.key = t3.key); -
Especificar tanto el orden como la dirección de unión en cada nivel:
/*+ Leading((t1 t2) t3) */ SELECT * FROM table1 t1 JOIN table2 t2 ON (t1.key = t2.key) JOIN table3 t3 ON (t2.key = t3.key);
Hints de corrección de número de filas
Corrigen las estimaciones de recuento de filas cuando el optimizador calcula valores incorrectos. Hay cuatro métodos de corrección disponibles:
Hints de ejecución paralela
Establecen el número de trabajadores paralelos para una tabla. Configure el recuento de trabajadores en 0 para deshabilitar la ejecución paralela.
El tercer parámetro controla qué configuraciones se modifican:
soft(predeterminado): modifica únicamentemax_parallel_workers_per_gather; el planificador controla el resto de las configuraciones.hard: modifica todas las configuraciones relacionadas del planificador.
Válido en: tablas ordinarias, tablas heredadas, tablas sin registro (unlogged) y tablas del sistema. Las tablas internas de una vista pueden referenciarse por su nombre real o por alias.
No válido en: tablas externas, cláusulas de valor constante, expresiones universales, vistas y subconsultas.
Ejemplo: ejecutar una consulta de unión con 3 trabajadores en c1 y 5 trabajadores en c2:
Hints de parámetros GUC
Modifican temporalmente el valor de un parámetro GUC durante la planificación de la consulta. Si el mismo parámetro GUC se establece más de una vez, prevalece el último valor.
Formatos de hints compatibles
| Categoría | Formato | Descripción |
|---|---|---|
| Métodos de escaneo | SeqScan(table) |
Fuerza un escaneo secuencial. |
TidScan(table) |
Fuerza un escaneo TID (identificador de tupla). | |
IndexScan(table [index...]) |
Fuerza un escaneo por índice. Opcionalmente, especifique el índice. | |
IndexOnlyScan(table [index...]) |
Fuerza un escaneo exclusivo por índice. Opcionalmente, especifique el índice. | |
BitmapScan(table [index...]) |
Fuerza un escaneo por mapa de bits. | |
NoSeqScan(table) |
Prohíbe el escaneo secuencial. | |
NoTidScan(table) |
Prohíbe el escaneo TID. | |
NoIndexScan(table) |
Prohíbe el escaneo por índice. | |
NoIndexOnlyScan(table) |
Prohíbe el escaneo exclusivo por índice. Solo se escanean las tablas. | |
NoBitmapScan(table) |
Prohíbe el escaneo por mapa de bits. | |
| Métodos de unión | NestLoop(table table [table...]) |
Fuerza una unión de bucle anidado. |
HashJoin(table table [table...]) |
Fuerza una unión hash. | |
MergeJoin(table table [table...]) |
Fuerza una unión por combinación. | |
NoNestLoop(table table [table...]) |
Prohíbe la unión de bucle anidado. | |
NoHashJoin(table table [table...]) |
Prohíbe la unión hash. | |
NoMergeJoin(table table [table...]) |
Prohíbe la unión por combinación. | |
| Orden de unión | Leading(table table [table...]) |
Especifica el orden de unión. |
Leading(<join pair>) |
Especifica el orden y la dirección de unión en cada nivel. | |
| Corrección de número de filas | Rows(table table [table...] correction) |
Corrige el recuento estimado de filas para una unión. Métodos de corrección: #<n> (establecer en n), +<n> (sumar n), -<n> (restar n), *<n> (multiplicar por n). <n> debe ser legible por la función strtod. |
| Ejecución paralela | Parallel(table <workers> [soft|hard]) |
Establece o prohíbe la ejecución paralela. Configure <workers> en 0 para deshabilitarla. Valor predeterminado: soft. |
| Parámetros GUC | Set(GUC-param value) |
Establece el valor de un parámetro GUC durante la planificación de la consulta. |
Para obtener más información, consulte pg_hint_plan.