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?