Seletiva Predicado Pushdown Para Visualizar

0

Pergunta

Eu tenho uma grande coluna de tabela de armazenamento que recebe atualizações frequentes. Eu não ingere as atualizações diretamente para a tabela de origem porque o que faria com que, na maioria dos casos, um pequeno número de atualizações para causar uma mesa cheia de micro partição de reconstrução. Em vez disso, eu fluxo de atualizações para uma atualização de tabela, e no momento da consulta eu combinam ambos. Na prática, isso funciona bem.

Para simplificar as coisas, eu vou jogar isso em um modo de exibição 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 o users tabela e user_changes tabela têm o mesmo regime, bem como a alguns de configuração da partição. Dessa forma, posso usar o predicado pushdown sobre o modo de exibição para selecionar somente usuários dentro da partição correta. Vamos dizer que este é o account_id.

SELECT * FROM users_view
WHERE account_id = 1234

Mas o users tabela é um pouco maior do que o user_changes tabela, e eu gostaria de empurrar ainda mais predicados para baixo para o users tabela sem empurrando adicionais predicados para baixo para o user_changes tabela. Por quê? Porque correspondência no users tabela, enquanto 98% de precisão, tem falso positivos/negativos. Os detalhes do user_changes são necessários para definir o recorde reta. O que esta seria a aparência exterior de um ponto de vista é 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'

Como desagradável como esta parece, é muito mais funcionais. Todas as condições podem ser aplicadas para maior users tabela, mas apenas imutável condições podem ser aplicados para a users_changes tabela. por exemplo, Um usuário pode alterar cidades, mas o usuário não pode alterar as contas. A segunda execução de todas as condições após a união é pegar qualquer alteração que o user_changes introduzido.

Isso é complicado para escrever, e, mais ainda, como a consulta se torna mais complicado e construtores de consulta se envolver. Então, eu estou procurando uma forma de maneira a convencer o sql planejador para ignorar predicado pushdown de alguns predicados no meu user_changes tabela sem a necessidade de formatar a uma consulta como esta. De preferência, com um modo de exibição.

PSUEDO SQL. PSUEDO SQL. PSUEDO SQL

Em meus sonhos mais loucos eu poderia dizer que o planejador de consulta onde ele pode usar a partição de predicados, e onde ele pode usar partição que não 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'

Qualquer idéias?

1

Melhor resposta

1

você pode adicionar colunas adicionais src para determinar a tabela de origem e enrole predicados no 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

Muito legal a idéia! Obrigado!
micah

@mica, você pode quebrar todos os predicados em um único CASO, usando E ou OU: then city = 'Chicago' AND one_more_condition AND some_other_condition
leftjoin

Em outros idiomas

Esta página está em outros idiomas

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