Controlli logici e problemi di performance all'interno di un conteggio (distinto foo)

StackOverflow https://stackoverflow.com//questions/22075809

  •  23-12-2019
  •  | 
  •  

Domanda

Ho una domanda regolare e molto costosa che devo correre, e sfortunatamente devo unirmi ai risultati di quella query con quasi esattamente la stessa query per ottenere un rapporto ... con conseguente uso di una query che prende il sopravvento 3 minuti da eseguire. Questo è quello che vorrei fare .... (supponendo che evitasse un join accederebbe il tempo di query)

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
.

Questo è ciò che sono costretto a fare ....

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
.

Tre problemi / domande:

    .
  1. Sembra che ci sia un modo in cui la grossa query potrebbe eseguire un conteggio (campo distinto) con una logica condizionale incorporata. C'è un modo per evitare di fare un join in questo scenario sopra?
  2. Count distinto con un valore superiore a 100.000 ha fallito per me. Mi piacerebbe essere in grado di fare un conteggio distinto di 10.000.000. Ci sono noti problemi di performance con il conteggio distinto e valori di grandi dimensioni? È questo essere indirizzato?
  3. Ci sono piani per poter utilizzare il nome del campo dichiarato / calcolato all'interno della selezione in un'altra istruzione in quella selezione? Nell'esempio migliore, vorrei usare i nomi per i risultati invece di ripetere la formula nella dichiarazione rotonda. (cioè mi piacerebbe specificare

    total_sunbutter_meals_per_day / total_meals Invece di

    conteggio (persona distinta, dove superiore (ingrediente) contiene "burro di sole", 100000) / conteggio (persona distinta, 10000000)

  4. Grazie in anticipo per l'aiuto!

È stato utile?

Soluzione

Domanda 1:

È possibile creare una query interiore con due campi distinti come segue:

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])
.

Domanda 2:

In BigQuery, il conteggio (distinto) restituisce un risultato approssimativo. Se si aumenta la soglia in cui vengono restituiti i risultati precisi, avrai danneggiato le prestazioni (e alla fine causare il fallimento della tua query) perché un singolo lavoratore deve tenere traccia di tutti questi valori distinti. Vedi conteggio bigquery (valore distinto) VS Count (valore) per ulteriori informazioni. .

Se la necessità di risultati precise in ottimalità del conteggio (distinto) è la scalabilità, l'alternativa è quella di utilizzare il gruppo ciascuno con il conteggio (*), che ti darà conteggi precisi per elementi distinti in modo scalabile.

Nota che dovrai affrontare il problema in questione 1 in un modo leggermente diverso. Qualcosa come:

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
.

Domanda 3:

In questo momento, non è possibile fare riferimento ad altri campi nella stessa istruzione SELECT, e non abbiamo ancora intenzione di aggiungere questa funzione. Ma puoi sempre avvolgere la tua query in un'altra query.

invece di:

SELECT 17 AS a, a + 1 AS b
.

Puoi scrivere:

SELECT a, a + 1 AS b FROM (SELECT 17 AS a)
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top