Google bigquery 计数内的逻辑检查和性能问题(不同的foo)

Google bigquery 计数内的逻辑检查和性能问题(不同的foo),google-bigquery,Google Bigquery,我需要运行一个常规且非常昂贵的查询,不幸的是,我必须将该查询的结果与几乎完全相同的查询连接起来,以获得一个比率。。。导致使用一个运行时间超过3分钟的查询。这就是我想做的。。。。假设避免连接会加快查询时间 SELECT date, meal, country, COUNT(DISTINCT person, WHERE UPPER(ingredient) CONTAINS "SUN BUTTER", 10000000) as total_sunbutter_meals

我需要运行一个常规且非常昂贵的查询,不幸的是,我必须将该查询的结果与几乎完全相同的查询连接起来,以获得一个比率。。。导致使用一个运行时间超过3分钟的查询。这就是我想做的。。。。假设避免连接会加快查询时间

SELECT
    date,
    meal,
    country,
    COUNT(DISTINCT person, WHERE UPPER(ingredient) CONTAINS "SUN BUTTER", 10000000) as total_sunbutter_meals_per_day
    COUNT(DISTINCT person, 10000000) as total_meals
    ROUND(100*total_sunbutter_meals_per_day/total_meals,1) as percentage_meals_sunbutter
FROM [project:dataset.menu]
GROUP BY date, meals, country
这是我被迫做的

SELECT
    total.date as date,
    total.meal as meal,
    total.country as country,
    total_sunbutter_meals_per_day,
    total_meals_per_day,
    ROUND(100*total_sunbutter_meals_per_day/total_meals,1) as percentage_meals_sunbutter
FROM
    (    
    SELECT
        date,
        meal,
        country,
        COUNT(DISTINCT person, 100000) as total_sunbutter_meals_per_day
    FROM [project:dataset.menu]
    WHERE    
        UPPER(ingredient) CONTAINS "SUN BUTTER"
    GROUP BY date, meals, country 
    ) as sunbutter
JOIN
    (
    SELECT
        date,
        meal,
        country,
        COUNT(DISTINCT person, 100000) as total_meals_per_day
    FROM [project:dataset.menu]
    GROUP BY date, meals, country 
    ) as total
ON total.date = sunbutter.date AND total.meal = sunbutter.meal AND total.country = sunbutter.country
三个问题:

似乎应该有一种方法可以让大查询使用一些嵌入式条件逻辑执行COUNTDISTINCT字段。有没有办法避免在上述场景中进行连接? 对我而言,值大于100000的计数不重复失败。我希望能数到10000000。是否存在计数不同和较大值的已知性能问题?这个问题正在解决吗? 是否计划在SELECT中的另一个语句中使用SELECT中声明/计算的字段名?在上面的示例中,我希望使用结果的名称,而不是在ROUND语句中重复公式。我想具体说明一下

sunbutter每天总餐数/总餐数 而不是

COUNTDISTINCT person,其中主要成分含有防晒霜,100000/COUNTDISTINCT person,10000000

提前感谢您的帮助

问题1:

您可以创建具有两个不同字段的内部查询,如下所示:

SELECT date, meal, country, COUNT(DISTINCT person) total_meals, COUNT(DISTINCT sunbutter_person) total_sunbutter_meals, FROM (SELECT date, meal, country, person, IF(UPPER(ingredient) CONTAINS "SUN BUTTER", person, NULL) sunbutter_person FROM [project:dataset.menu]) 问题2:

在BigQuery中,COUNTDISTINCT返回一个近似结果。如果提高返回精确结果的阈值,将影响性能并最终导致查询失败,因为单个工作人员需要跟踪所有这些不同的值。有关更多信息,请参阅

如果您对精确结果的需求超过了COUNTDISTINCT的可伸缩性,那么另一种选择是使用GROUP BY with COUNT*,这将以可伸缩的方式为不同的元素提供精确的计数

请注意,您需要以稍微不同的方式解决问题1中的问题。比如:

SELECT date, meal, country, COUNT(*) total_meals, SUM(sunbutter) total_sunbutter_meals, FROM (SELECT date, meal, country, IF(UPPER(ingredient) CONTAINS "SUN BUTTER", 1, 0) sunbutter, FROM [project:dataset.menu] GROUP EACH BY date, meal, country, person) GROUP BY date, meal, country 问题3:

现在,您不能在同一SELECT语句中引用其他字段,我们还没有计划添加该功能。但您始终可以将查询包装到另一个查询中

而不是:

SELECT 17 AS a, a + 1 AS b 你可以写:

SELECT a, a + 1 AS b FROM (SELECT 17 AS a)
谢谢你非常详尽的答复。我在一些关注的问题上测试了上面的逻辑,你的建议很有效。但是,如果避免使用COUNTDISTINCT,并在外部查询中使用带有GROUP-EACH-BY-then COUNT*的内部查询,则似乎没有性能优势。我希望会有一些性能优势。无论如何,你的建议帮助我消除了使用COUNTDISTINCT的必要性。这有点困难。对于较低的阈值,使用COUNTDISTINCT可能更快,因为每个节点需要保留的数据更少。当您提高准确结果的阈值时,您可能会看到性能降低,最终您的查询将完全失败。使用GROUP EACH BY,您需要预先支付洗牌数据的费用,也就是说,根据组密钥将数据分发到节点,但从这一点开始,所有内容都可以很好地扩展。