【发布时间】:2022-01-01 23:29:12
【问题描述】:
我有一个经常更新的大型列存储表。我不会将更新直接摄取到源表中,因为在大多数情况下,这会导致少量更新导致全表微分区重建。相反,我将更新流式传输到更新表,并在查询时将两者结合起来。在实践中,这很有效。
所以把事情简化一下,我会把它放在一个视图中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
)
users 表和user_changes 表具有相同的方案以及一些分区配置。这样,我可以在视图上使用谓词下推来仅选择正确分区内的用户。假设这是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 表上某些谓词的谓词下推,而无需像这样格式化查询。最好有风景。
伪 SQL。伪 SQL。伪 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'
有什么疯狂的想法吗?
【问题讨论】:
-
您是否正在使用已经硬编码的谓词创建视图?如果我的问题正确,您想简化查询构建,以便仅在查询结束时应用谓词(仍在视图内)?
-
理想情况下,我希望将视图视为一个知道如何将正确谓词应用于每个表的黑盒。我想将完整的谓词应用于我的
users表,但要手动选择要应用于user_changes表的谓词。所以是的——这将是为了简化查询构建过程。
标签: sql snowflake-cloud-data-platform where-clause predicate