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