Selectiva Predicado Pushdown Para Ver

0

Pregunta

Tengo una gran columna de la tabla del almacén, que se actualiza con frecuencia. Yo no ingerir las actualizaciones directamente en la tabla de origen, porque eso haría que, en la mayoría de los casos, un pequeño número de actualizaciones a causa de una mesa llena de micro partición de la reconstrucción. En lugar de eso me transmitir las actualizaciones a una actualización de la tabla, y en el momento de la consulta puedo combinar ambos. En la práctica, esto funciona bien.

Para simplificar las cosas, voy a tirar esto en una vista users_view.

CREATE OR REPLACE VIEW users_view AS (
    SELECT * FROM users
    UNION ALL 
    SELECT * FROM user_changes
    QUALIFY ROW_NUMBER() OVER(
        PARTITION BY id 
        ORDER BY last_updated_at DESC
    ) = 1
)

Tanto el users tabla y user_changes tabla tienen el mismo esquema, así como algunas de configuración de la partición. De esta forma, se puede utilizar el predicado pushdown en la vista de seleccionar sólo los usuarios dentro de la partición correcta. Digamos que este es el account_id.

SELECT * FROM users_view
WHERE account_id = 1234

Pero el users la tabla es un poco más grande que el user_changes mesa, y me gustaría empujar aún más los predicados de abajo a la users la tabla sin tratar de predicados adicionales hasta el user_changes tabla. Por qué? Debido a la coincidencia en el users de la tabla, mientras que el 98% de precisión, tiene falsos positivos/negativos. Los detalles de la user_changes son necesarios para establecer el record. Cómo se vería fuera de un punto de vista es este:

SELECT * FROM (
    SELECT * FROM users
    WHERE account_id = 1234 AND city = 'Chicago'
    UNION ALL 
    SELECT * FROM user_changes
    WHERE account_id = 1234
    QUALIFY ROW_NUMBER() OVER(
        PARTITION BY id 
        ORDER BY last_updated_at DESC
    ) = 1
)
WHERE account_id = 1234 AND city = 'Chicago'

Tan desagradable como este aspecto, es mucho más eficientes. Todas las condiciones se pueden aplicar a la mucho mayor users la tabla, pero sólo inmutable condiciones pueden ser aplicadas a la users_changes tabla. es decir, Un usuario puede cambiar las ciudades, pero el usuario no puede cambiar las cuentas. El segundo de ejecución de todas las condiciones después de que el sindicato es capturar a los cambios que el user_changes introducido.

Esto es incómodo para escribir, y más aún cuando la consulta se convierte en complicado y consulta de los constructores de participar. Así que estoy buscando la manera de convencer a la de sql planificador para saltar predicado pushdown de algunos de los predicados en mi user_changes la tabla sin necesidad de formatear la consulta como esta. Idealmente con una vista.

PSEUDO SQL. PSEUDO SQL. PSEUDO SQL

En mis sueños yo podría decir que el planificador de consultas donde se puede utilizar la partición de los predicados, y donde se puede utilizar no-partición de los predicados.

CREATE OR REPLACE VIEW users_view AS (
    SELECT * FROM (
        SELECT * FROM users
        %PARTITION_PREDICATES%
        %NON_PARTITION_PREDICATES%

        UNION ALL 

        SELECT * FROM user_changes
        %PARTITION_PREDICATES%

        QUALIFY ROW_NUMBER() OVER(
            PARTITION BY id 
            ORDER BY last_updated_at DESC
        ) = 1
    )
    %PARTITION_PREDICATES%
    %NON_PARTITION_PREDICATES%
)

SELECT * FROM users_view
WHERE account_id = 1234 AND city = 'Chicago'

Cualquier locas ideas?

1

Mejor respuesta

1

usted puede agregar columna adicional src para la determinación de la tabla de origen y la envoltura de los predicados en el CASO:

select * from
(
SELECT u.*, 'users' as src FROM users u
union all
SELECT uc.*, 'users_changes' as src FROM users_changes uc
) 
WHERE --applied only to users
      case when src  = 'users' 
                 then city = 'Chicago' --predicate wrapped in case
           else true
       end
  --applied to all
  AND account=12345 
2021-11-23 14:58:40

Idea muy cool! Gracias!
micah

@micah puede envolver todos los predicados en el único CASO en el que el uso de Y o O: then city = 'Chicago' AND one_more_condition AND some_other_condition
leftjoin

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................