BigQuery - 增加特定表的处理时间

Posted

技术标签:

【中文标题】BigQuery - 增加特定表的处理时间【英文标题】:BigQuery - Increased processing time with specific table 【发布时间】:2014-06-19 15:08:24 【问题描述】:

我们已经对 2 对不同的表执行了 2 次查询(一些用于检索更新数据和内容的连接),相同的(表和查询)格式和目标。查询之间的区别在于 REGEXP_MATCH 字符串中包含的字符串变量(Regex 公式具有相同的格式,只是核心字符串不同)。其余部分完全相同,当然,所包含的数据除外。

即使查询在 20-50 秒内处理了一对表上的近 2GB 数据,但具有不同 REGEX 参数(相同列)的同一查询在 100 多秒内处理另一对表 250 MB(有时甚至500 到 1000+ 秒)。两个查询都以交互模式执行,不缓存结果。

这可能是什么原因,有解决办法吗?

考虑到运行的查询基本相同,与明显较大的表相比,较小的表如何可能需要大量的处理时间?

对不起,下面的混乱,试图让它尽可能漂亮。 因此,简要介绍一下:查询打算根据他们的事件创建一个用户漏斗。数据是实时的,所以我们有更新的用户和事件。包括的步骤如下:

获取“完成”操作 - 从第一个正则表达式选择的更新事件中获取用户 获取“不得执行”操作 - 从第二个事件选择的更新事件中获取用户 在 LEFT OUTER JOIN 的帮助下创建两者之间的差异 将选定的用户加入到 USERS 表中(同时获取更新的用户)

如果您需要更多详细信息,请告诉我。我会尽量把一切都说清楚。

SELECT Count(*) as count
FROM 
    (
    SELECT final._nid as _nid
    FROM (
        -- Start of events funnel
        SELECT did.user as user
        FROM (
            -- Get updated events
            SELECT events.user as user, events.createdOn as createdOn
            FROM [shop1_events] as events
            JOIN EACH (
                SELECT session, createdOn, MAX(updatedOn) as updatedOn
                FROM [shop1_events]
                GROUP EACH BY session, createdOn) as latest_events
            ON events.session = latest_events.session AND events.createdOn = latest_events.createdOn AND events.updatedOn = latest_events.updatedOn
            -- Regex for categories (concatenated categories)
            WHERE ((REGEXP_MATCH(events.category_a , r"([\:\^]100000453[\:\^]|^100000453$|^100000453[\^\:]|[\^\:]100000453$)"))) AND events.type = 10006) as did
        -- Exclude the following events:    
        LEFT OUTER JOIN EACH (
            -- Get updated events
            SELECT events.user as user, events.createdOn as createdOn
            FROM [shop1_events] as events
            JOIN EACH (
                SELECT session, createdOn, MAX(updatedOn) as updatedOn
                FROM [shop1_events]
                GROUP EACH BY session, createdOn) as latest_events
            ON events.session = latest_events.session AND events.createdOn = latest_events.createdOn AND events.updatedOn = latest_events.updatedOn
            -- Regex for categories
            WHERE ((REGEXP_MATCH(events.category_a , r"([\:\^]100000485[\:\^]|^100000485$|^100000485[\^\:]|[\^\:]100000485$)"))) AND events.type = 10006) as step_not_0
        ON did.user = step_not_0.user
        WHERE step_not_0.user IS NULL) as funnel
    JOIN EACH (
        -- Join with users
        SELECT all._nid as _nid
        FROM [shop1_users] as all
        JOIN EACH (
            -- Get updated users
            SELECT _nid, MAX(updatedOn) as updatedOn
            FROM [shop1_users]
            GROUP EACH BY _nid) as latest
        ON all._nid = latest._nid AND all.updatedOn = latest.updatedOn
        ) as final
ON final._nid = funnel.user
GROUP EACH BY _nid) as counting;

【问题讨论】:

添加查询和 - 或至少 - 正则表达式。 添加了问题详情 :) 我认为如果两个测试中的差异仅仅是并且只有正则表达式字符串。那么也许您不需要为您的特定设置提供所有其他信息以获得更好的答案。导致延迟的两个单独查询中的两个正则表达式字符串是什么?我在您的代码中看到两个字符串,但它们在同一个查询下。 问题是我不确定正则表达式是否存在问题,因为执行查询的表也不同。正则表达式如下:([\:\^]<category>[\:\^]|^<category>$|^<category>[\^\:]|[\^\:]<category>$) 2 个表的 参数也不同。此外,简单查询有时具有不成比例的处理时间(对于较小的表来说时间明显更长)。 BigQuery 现在有一个名为“解释”的新功能。运行两个查询,并使用解释分析结果,以更好地理解它们为何如此不同。如果这没有帮助,请获取工作 ID 并将其发布在此处。然后 BigQuery 工程团队的人员应该可以查看一下。 【参考方案1】:

也许这有帮助:

也许您可以提取重要的值并将其与您的值进行比较,而不是运行正则表达式:

例子:

替换这个

REGEXP_MATCH(events.category_a , r"([\:\^]100000485[\:\^]|^100000485$|^100000485[\^\:]|[\^\:]100000485$)"))) 

为此:

REGEXP_REPLACE(events.category_a, r"\D*(\d+)\D*", (\1)) = "100000485"

【讨论】:

感谢您的回答,但这只会让我觉得我错误地提出了我的问题。对我的问题的简短改写:鉴于运行的查询基本相同,与大得多的表相比,较小的表如何可能需要大量的处理时间? @AlinLacea,好吧,我没有解释太多,但是,正则表达式可能需要很长时间,具体取决于处理的数据和有效性。我不确定这是否是您的查询的问题,这只是提示您改进它的最简单方法。【参考方案2】:

处理的数据量只说明第一阶段读取了多少数据。但是,查询的成本可能与此没有直接关系。例如。 JOIN 或 WHERE 子句可能会由于不匹配而在一种情况下消除大多数记录,但在另一种情况下留下记录。或者,一个表中可能存在一些偏差(特定的 JOIN 键经常出现) - 这会导致查询运行缓慢。影响性能的变量有很多。

您可以做什么 - 运行查询后,单击 Explanation 按钮,并检查每种情况下哪些步骤花费的时间最多,以及在此步骤中处理了多少行。这些值提供了对查询性能的更深入了解,而不仅仅是从原始表中读取了多少字节。

附:查询也可能受益于称为过滤器下推的小重写:

    SELECT events.user as user, events.createdOn as createdOn
    FROM [shop1_events] as events
    JOIN EACH (...) as latest_events
    ON ...
    WHERE <condition-for-events-table>

进入

    SELECT events.user as user, events.createdOn as createdOn
    FROM (SELECT <fields-used> FROM [shop1_events] 
          WHERE <condition-for-events-table>) as events
    JOIN EACH (...) as latest_events
    ON ...

【讨论】:

以上是关于BigQuery - 增加特定表的处理时间的主要内容,如果未能解决你的问题,请参考以下文章

如何关联多个 BigQuery 数组字段?

连接 BigQuery 和 Google 表格 - 日期参数问题

如何在不使用 Join 的情况下处理引用其他表的相关子查询的问题

BigQuery INSERT DML 语句限制

查找要插入 BigQuery 的列名

查找在 BigQuery 中创建表的查询