Crea y administra sugerencias con nombre

Para controlar cómo el planificador de consultas de AlloyDB para PostgreSQL genera planes de ejecución sin modificar las consultas de tu aplicación, puedes crear, verificar, ver, habilitar, inhabilitar y borrar sugerencias con nombre. Las sugerencias con nombre asocian una consulta con un conjunto de sugerencias que especifican detalles del plan de ejecución preferido. Cuando el planificador de consultas genera un plan de ejecución para la consulta asociada, aplica las sugerencias y las vuelve a aplicar de forma automática en las ejecuciones posteriores de la consulta. Por ejemplo, puedes usar sugerencias con nombre para forzar un análisis de índice en lugar de un análisis secuencial en una tabla o para aplicar un orden de unión específico en varias tablas.

Las sugerencias con nombre en AlloyDB admiten todas las sugerencias de la extensión pg_hint_plan de código abierto y las siguientes sugerencias para el motor de columnas:

  • ColumnarScan(table): fuerza un análisis de columnas en la tabla.

  • NoColumnarScan(table): inhabilita un análisis de columnas en la tabla.

AlloyDB te permite crear sugerencias con nombre para consultas parametrizadas y no parametrizadas, a las que este documento se refiere como consultas sensibles a los parámetros.

Flujo de trabajo

Para usar sugerencias con nombre, sigue estos pasos:

  1. Identifica la consulta para la que deseas crear sugerencias con nombre.

  2. Crea sugerencias con nombre con sugerencias que se aplicarán cuando se vuelva a ejecutar la consulta.

  3. Verifica la aplicación de las sugerencias con nombre.

En esta página, se usan la siguiente tabla y el índice para los ejemplos:

CREATE TABLE t(a INT, b INT);
CREATE INDEX t_idx1 ON t(a);
  DROP EXTENSION IF EXISTS google_auto_hints;

Para seguir usando las sugerencias con nombre que creaste con una versión anterior, vuelve a crearlas siguiendo las instrucciones de esta página.

Antes de comenzar

  • Habilita la función de sugerencias con nombre en tu instancia. Establece la marca alloydb.enable_named_hints en on. Puedes habilitar esta marca a nivel de todo el servidor o de la sesión. Para minimizar la sobrecarga que podría resultar del uso de esta función, habilita esta marca solo a nivel de sesión.

    Para obtener más información, consulta Configura las marcas de base de datos de una instancia.

    Para verificar que la marca esté habilitada, ejecuta el comando show alloydb.enable_named_hints;. Si la marca está habilitada, el resultado devuelve "on".

  • Para cada base de datos en la que desees usar sugerencias con nombre, crea una extensión en la base de datos desde la instancia principal de AlloyDB como el usuario alloydbsuperuser o postgres:

    CREATE EXTENSION google_auto_hints CASCADE;
    

Roles obligatorios

Para obtener los permisos que necesitas para crear y administrar sugerencias con nombre, pídele a tu administrador que te otorgue los siguientes roles de Identity and Access Management (IAM):

Si bien el permiso predeterminado solo permite que el usuario con el rol alloydbsuperuser cree sugerencias con nombre, de manera opcional, puedes otorgar el permiso de escritura a los otros usuarios o roles de la base de datos para que puedan crear sugerencias con nombre.

GRANT INSERT,DELETE,UPDATE ON hint_plan.plan_patches, hint_plan.hints TO role_name;
GRANT USAGE ON SEQUENCE hint_plan.hints_id_seq, hint_plan.plan_patches_id_seq TO role_name;

Identifica la consulta

Puedes usar el ID de consulta para identificar la consulta cuyo plan predeterminado necesita ajustes. El ID de consulta estará disponible después de que se ejecute la consulta al menos una vez.

Usa los siguientes métodos para identificar el ID de consulta:

  • Ejecuta el comando EXPLAIN (VERBOSE), como se muestra en este ejemplo:

    EXPLAIN (VERBOSE) SELECT * FROM t WHERE a = 99;
                            QUERY PLAN
    ----------------------------------------------------------
    Seq Scan on public.t  (cost=0.00..38.25 rows=11 width=8)
      Output: a, b
      Filter: (t.a = 99)
    Query Identifier: -6875839275481643436
    

    En el resultado, el ID de la consulta es -6875839275481643436.

  • Consulta la vista pg_stat_statements.

    Si habilitaste la extensión pg_stat_statements, puedes encontrar el ID de la consulta con una consulta a la vista pg_stat_statements, como se muestra en el siguiente ejemplo:

    select query, queryid from pg_stat_statements;
    

Crea sugerencias con nombre

Para crear sugerencias con nombre, usa la función google_create_named_hints(), que crea una asociación entre la consulta y las sugerencias en la base de datos.

SELECT google_create_named_hints(
HINTS_NAME=>'HINTS_NAME',
SQL_ID=>QUERY_ID,
SQL_TEXT=>QUERY_TEXT,
APPLICATION_NAME=>'APPLICATION_NAME',
HINTS=>'HINTS',
DISABLED=>DISABLED);

Reemplaza lo siguiente:

  • HINTS_NAME: un nombre para las sugerencias con nombre. Debe ser único dentro de la base de datos.
  • SQL_ID (opcional): Es el ID de la consulta para la que estás creando las sugerencias con nombre.

    Puedes usar el ID o el texto de la consulta (el parámetro SQL_TEXT) para crear sugerencias con nombre. Sin embargo, te recomendamos que uses el ID de consulta para crear sugerencias con nombre, ya que AlloyDB ubica automáticamente el texto de la consulta normalizado en función del ID de consulta.

  • SQL_TEXT (opcional): Es el texto de la consulta para la que creas las sugerencias con nombre.

    Cuando usas el texto de la consulta, este debe ser el mismo que el de la consulta prevista, excepto por los valores literales y constantes de la consulta. Cualquier discrepancia, incluida la diferencia de mayúsculas y minúsculas, puede provocar que no se apliquen las sugerencias con nombre. Para aprender a crear sugerencias con nombre para consultas con literales y constantes, consulta Crea sugerencias con nombre sensibles a los parámetros.

  • APPLICATION_NAME (opcional): Es el nombre de la aplicación cliente de la sesión para la que deseas usar las sugerencias con nombre. Una cadena vacía te permite aplicar las sugerencias con nombre a la consulta, independientemente de la aplicación cliente que emita la consulta.

  • HINTS: Es una lista separada por espacios de las sugerencias para la consulta.

  • DISABLED (opcional): BOOL. Si es TRUE, crea las sugerencias con nombre inicialmente como inhabilitadas.

Ejemplo:

SELECT google_create_named_hints(
HINTS_NAME=>'my_hint1',
SQL_ID=>-6875839275481643436,
SQL_TEXT=>NULL,
APPLICATION_NAME=>'',
HINTS=>'IndexScan(t)',
DISABLED=>NULL);

Esta consulta crea una sugerencia con nombre llamada my_hint1. El planificador aplica su sugerencia IndexScan(t) para forzar un análisis de índice en la tabla t en la próxima ejecución de esta consulta de ejemplo.

Después de crear sugerencias con nombre, puedes usar google_named_hints_view para confirmar si se crearon, como se muestra en el siguiente ejemplo:

postgres=>\x
postgres=>select * from google_named_hints_view limit 1;
-[ RECORD 1 ]-----+-----------------------------
hints_name | my_hint1
sql_id | -6875839275481643436
id | 9
query_string | SELECT * FROM t WHERE a = ?;
application_name |
hints | IndexScan(t)
disabled | f

Después de que se crean las sugerencias con nombre en la instancia principal, se aplican automáticamente a las consultas asociadas en la instancia del grupo de lectura, siempre y cuando también hayas habilitado la función de sugerencias con nombre en la instancia del grupo de lectura.

Crea sugerencias con nombre sensibles a los parámetros

De forma predeterminada, cuando se crean sugerencias con nombre para una consulta, el texto de la consulta asociado se normaliza reemplazando cualquier valor literal y constante en el texto de la consulta por un marcador de parámetro, como ?. Luego, las sugerencias con nombre se usan para esa consulta normalizada, incluso con un valor diferente para el marcador de parámetro.

Por ejemplo, ejecutar la siguiente consulta permite que otra consulta, como SELECT * FROM t WHERE a = 99;, use las sugerencias con nombre my_hint2 de forma predeterminada.

SELECT google_create_named_hints(
  HINTS_NAME=>'my_hint2',
  SQL_ID=>NULL,
  SQL_TEXT=>'SELECT * FROM t WHERE a = ?;',
  APPLICATION_NAME=>'',
  HINTS=>'SeqScan(t)',
  DISABLED=>NULL);

Luego, una consulta, como SELECT * FROM t WHERE a = 99;, puede usar las sugerencias con nombre my_hint2 de forma predeterminada.

AlloyDB también te permite crear sugerencias con nombre para textos de consulta no parametrizados, en los que cada valor literal y constante en el texto de la consulta es significativo cuando se buscan coincidencias con las consultas.

Cuando aplicas sugerencias con nombre sensibles a los parámetros, dos consultas que solo difieren en los valores literales o constantes correspondientes también se consideran diferentes. Si quieres forzar planes para ambas consultas, debes crear sugerencias con nombre independientes para cada consulta. Sin embargo, puedes usar sugerencias diferentes para las dos sugerencias con nombre.

Para crear sugerencias con nombre sensibles a los parámetros, establece el parámetro SENSITIVE_TO_PARAM de la función google_create_named_hints() en TRUE, como se muestra en el siguiente ejemplo:

SELECT google_create_named_hints(
HINTS_NAME=>'my_hint3',
SQL_ID=>NULL,
SQL_TEXT=>'SELECT * FROM t WHERE a = 88;',
APPLICATION_NAME=>'',
HINTS=>'IndexScan(t)',
DISABLED=>NULL,
SENSITIVE_TO_PARAM=>TRUE);

La consulta SELECT * FROM t WHERE a = 99; no puede usar las sugerencias con nombre my_hint3, porque el valor literal "99" no coincide con "88".

Cuando uses sugerencias con nombre sensibles a los parámetros, ten en cuenta lo siguiente:

  • Las sugerencias con nombre sensibles a los parámetros no admiten una combinación de valores literales y constantes, ni marcadores de parámetros en el texto de la consulta.
  • Cuando creas sugerencias con nombre sensibles a los parámetros y sugerencias con nombre predeterminadas para la misma consulta, se prefieren las sugerencias con nombre sensibles a los parámetros sobre las sugerencias con nombre predeterminadas.
  • Si deseas usar el ID de consulta para crear sugerencias con nombre sensibles a los parámetros, asegúrate de que la consulta se haya ejecutado en la sesión actual. Los valores de los parámetros de la ejecución más reciente (en la sesión actual) se usan para crear las sugerencias con nombre.

Verifica la aplicación de las sugerencias con nombre

Después de crear las sugerencias con nombre, usa los siguientes métodos para verificar que el plan de consulta se aplique de forma forzada según corresponda.

  • Usa el comando EXPLAIN o el comando EXPLAIN (ANALYZE).

    Para ver las sugerencias que el planificador intenta aplicar, puedes establecer las siguientes marcas a nivel de la sesión antes de ejecutar el comando EXPLAIN:

    SET pg_hint_plan.debug_print = ON;
    SET client_min_messages = LOG;
    
  • Usa la extensión auto_explain.

Administra las sugerencias con nombre

AlloyDB te permite ver, habilitar, inhabilitar y borrar sugerencias con nombre.

Visualiza sugerencias con nombre

Para ver las sugerencias con nombre existentes, usa la función google_named_hints_view, como se muestra en el siguiente ejemplo:

postgres=>\x
postgres=>select * from google_named_hints_view limit 1;
-[ RECORD 1 ]-----+-----------------------------
hints_name | my_hint1
sql_id | -6875839275481643436
id | 9
query_string | SELECT * FROM t WHERE a = ?;
application_name |
hints | IndexScan(t)
disabled | f

Habilita las sugerencias con nombre

Para habilitar las sugerencias con nombre existentes, usa la función google_enable_named_hints(HINTS_NAME). De forma predeterminada, las sugerencias con nombre se habilitan cuando las creas.

Por ejemplo, para volver a habilitar las sugerencias con nombre my_hint1 inhabilitadas anteriormente de la base de datos, ejecuta la siguiente función:

SELECT google_enable_named_hints('my_hint1');

Inhabilitar sugerencias con nombre

Para inhabilitar las sugerencias con nombre existentes, usa la función google_disable_named_hints(HINTS_NAME).

Por ejemplo, para borrar las sugerencias con nombre de ejemplo my_hint1 de la base de datos, ejecuta la siguiente función:

SELECT google_disable_named_hints('my_hint1');

Borra sugerencias con nombre

Para borrar sugerencias con nombre, usa la función google_delete_named_hints(HINTS_NAME).

Por ejemplo, para borrar las sugerencias con nombre de ejemplo my_hint1 de la base de datos, ejecuta la siguiente función:

SELECT google_delete_named_hints('my_hint1');

Inhabilita la función de sugerencias con nombre

Para inhabilitar la función de sugerencias con nombre en tu instancia, establece la marca alloydb.enable_named_hints en off. Para obtener más información, consulta Configura las marcas de base de datos de una instancia.

Limitaciones

El uso de sugerencias con nombre tiene las siguientes limitaciones:

  • Cuando usas un ID de consulta para crear sugerencias con nombre, el texto de la consulta original tiene una limitación de longitud de 2,048 caracteres.
  • Dada la semántica de una consulta compleja, no todas las sugerencias y sus combinaciones se pueden aplicar por completo. Te recomendamos que pruebes las sugerencias previstas en tus consultas antes de implementar las sugerencias con nombre en producción.
  • La aplicación de órdenes de unión para consultas complejas es limitada.
  • El uso de sugerencias con nombre para influir en la selección del plan puede interferir en las mejoras futuras del optimizador de AlloyDB. Asegúrate de volver a considerar la opción de usar sugerencias con nombre y ajustarlas según corresponda cuando ocurran los siguientes eventos:

    • Hay un cambio significativo en la carga de trabajo.
    • Hay un nuevo lanzamiento o actualización de AlloyDB que incluye cambios y mejoras en el optimizador.
    • Se aplican otros métodos de ajuste de consultas a las mismas consultas.
    • El uso de sugerencias con nombre agrega una sobrecarga significativa al rendimiento del sistema.

Para obtener más información sobre las limitaciones, consulta la documentación de pg_hint_plan.

Pasos siguientes