选择性谓词下推到视图



我有一个大的列存储表,它可以频繁更新。我不会将更新直接接收到源表中,因为在大多数情况下,这会导致少量更新,从而导致整个表的微分区重建。相反,我将更新流式传输到更新表中,并在查询时将两者结合起来。在实践中,效果很好。

所以简化一下,我将把它放在视图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
)

CCD_ 2表和CCD_ 3表具有相同的方案以及一些分区配置。通过这种方式,我可以在视图上使用谓词下推,只选择正确分区中的用户。假设这是account_id

SELECT * FROM users_view
WHERE account_id = 1234

但是users表比user_changes表大很多,我想将更多的谓词下推到users表,而不将额外的谓词下压到user_changes表。为什么?因为users表上的匹配虽然准确率为98%,但存在误报/漏报。需要user_changes中的详细信息来澄清记录。这在视图之外会是什么样子:

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'

尽管这看起来很恶心,但它更具表演性。所有条件都可以应用于更大的users表,但只有不变的条件可以应用于users_changes表。即用户可以更改城市,但用户不能更改帐户。在并集之后,所有条件的第二次运行是捕获user_changes引入的任何更改。

这编写起来很麻烦,而且随着查询变得复杂和查询构建器的介入,情况更是如此。因此,我正在寻找说服sql计划器跳过user_changes表上某些谓词的谓词下推的方法,而不需要像这样格式化查询。理想情况下有视野。

PSUEDO SQL。PSUEDO-SQL。PSUEDO SQL

在我最疯狂的梦想中,我可以告诉查询规划器在哪里可以使用分区谓词,在哪里可以用非分区谓词。

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'

有什么疯狂的想法吗?

您可以添加额外的列src来确定CASE:中的源表和包装谓词

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 

最新更新