【问题标题】:Cannot query over table without a filter that can be used for partition elimination无法在没有可用于分区消除的过滤器的情况下查询表
【发布时间】:2018-07-05 14:39:22
【问题描述】:

我有一个分区表,很想使用 MERGE 语句,但由于某种原因不起作用。

MERGE `wr_live.p_email_event`  t
using `wr_live.email_event` s
on t.user_id=s.user_id and t.event=s.event and t.timestamp=s.timestamp
WHEN NOT MATCHED THEN
INSERT (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
values (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)

我明白了

如果没有过滤器,则无法查询表 'wr_live.p_email_event' 可用于分区消除。

正确的语法是什么?还有一种方法可以表达更短的插入内容吗?不命名所有列?

【问题讨论】:

    标签: google-bigquery


    【解决方案1】:

    正确的语法是什么?

    您可以从错误消息中看到 - 您的分区 wr_live.p_email_event 表是在 require partition filter 设置为 true 的情况下创建的。这意味着对该表的任何查询都必须在相应的分区字段上具有一些过滤器

    假设 timestamp 是分区字段 - 您可以执行以下操作

    MERGE `wr_live.p_email_event`  t
    USING `wr_live.email_event` s
    ON t.user_id=s.user_id AND t.event=s.event AND t.timestamp=s.timestamp
    AND DATE(t.timestamp) > CURRENT_DATE()  -- this is the filter you should tune 
    WHEN NOT MATCHED THEN
    INSERT (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)
    VALUES (user_id,event,engagement_score,dest_email_domain,timestamp,tags,meta)   
    

    所以你需要做下面的行,这样它实际上不会过滤掉你需要参与的任何内容

    AND DATE(t.timestamp) <> CURRENT_DATE()  -- this is the filter you should tune 
    

    例如,我发现,将其设置为将来的时间戳 - 在许多情况下可以解决问题,例如

    AND DATE(t.timestamp) > DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)   
    

    当然,如果您的wr_live.email_event 表也分区,require partition filter 设置为 true - 您需要为 s.timestamp 添加相同的过滤器

    还有什么方法可以表达更短的插入内容?没有命名所有列?

    BigQuery DML 的 INSERT 需要 column names to be specified - 没有办法(至少我知道)使用 INSERT 语句来避免它
    同时,您可以通过从查询结果中使用 DDL 的 CREATE TABLE 来避免这种情况。这不需要列出列

    例如,如下所示

    CREATE OR REPLACE TABLE `wr_live.p_email_event`
    PARTITION BY DATE(timestamp) AS
    SELECT * FROM `wr_live.p_email_event` 
    WHERE DATE(timestamp) <> DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
    UNION ALL 
    SELECT * FROM `wr_live.email_event` s
    WHERE NOT EXISTS (
      SELECT 1 FROM `wr_live.p_email_event` t
      WHERE t.user_id=s.user_id AND t.event=s.event AND t.timestamp=s.timestamp
      AND DATE(t.timestamp) > DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY)
    )
    

    您可能还想通过 OPTIONS() 包含表格选项列表 - 但看起来尚不支持过滤器属性 - 因此,如果您确实拥有/需要它 - 上面将“删除”此属性:o(

    【讨论】:

    • 感谢您的提醒——我认为将 require_partition_filter 与 CREATE TABLE 一起使用应该可以,但我们需要记录它。
    • 太棒了。谢谢@ElliottBrossard
    猜你喜欢
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多