2015-06-06 17 views
5

Sono nuovo di Google Big Query (e Stack Overflow), principalmente testando la velocità con cui Big Query riesce a elaborare query ben predisposte e mal fatte.GROUP BY problemi in Google Big Query

Ho difficoltà con una query ingombrante che viene eseguita (lentamente) su MySQL. Big Query si lamenta dei contenuti di GROUP BY. Ecco la query di partenza:

SELECT nonstops.term, nonstops.lincat, nonstops.id, 
MIN(
(1-((LEAST(1,minusone.catimp/nonstops.catimp) + LEAST(1,minusone.catweb/nonstops.catweb))/2))* 
(1-((LEAST(1,minusone.catimp/nonstops.catimp) + LEAST(1,minusone.catweb/nonstops.catweb))/2))* 
(1-((LEAST(1,minusone.catimp/nonstops.catimp) + LEAST(1,minusone.catweb/nonstops.catweb))/2))* 
(nonstops.catweb * nonstops.catweb * nonstops.catimp/nonstops.fnvweb/nonstops.fnvimp) 
) 
AS calc FROM nonstops INNER JOIN EACH minusone ON nonstops.lincat = minusone.lincat AND nonstops.term = minusone.term 
WHERE nonstops.lincat = 556 GROUP BY nonstops.term, nonstops.lincat 
ORDER BY `calc` DESC 

Nota che "EACH" viene aggiunto all'INNER JOIN poiché entrambe le tabelle sono grandi. Ho rimosso il nome del set di dati per renderlo più facile da leggere.

Il GROUP BY ha lo scopo di restituire solo il valore più basso del calcolo effettuato dal join per ciascun termine/coppia di valori.

L'errore che ottengo è:

(L1: 62): Espressione 'phrases.nonstops.id' non è presente nella lista GROUP BY

Che io non voglio in GROUP BY, ma ho aggiunto e ho quindi ottenere:

Espressione 'calc' non è presente nella lista GROUP BY

che anche io non volere! Ma se aggiungo io ottenere:

(L7: 1): Impossibile gruppo da un aggregato

ho guardato la documentazione e cercato una risposta, ma senza fortuna. Qualsiasi suggerimento o collegamento sarebbe più apprezzato.

risposta

3

Quando si raggruppa per qualcosa in BigQuery (o in qualsiasi SQL) i campi risultanti devono essere campi o aggregazioni di gruppo.

Altrimenti, quale valore di nonstops.id dovresti ottenere? Potrebbero esserci molti associati a una coppia di (nonstops.term, nonstops.lincat).

È possibile selezionare invece il campo ID max, min, ecc. raggruppa per questo campo (ma poi ottieni il calcolo per ogni tupla di termini, lingcat e id); o semplicemente rimuovi questo campo se non ne hai bisogno - se vuoi il risultato dell'espressione 'calc' per ogni coppia (nonstops.term, nonstops.lincat).

Il motivo per cui BigQuery si lamenta di `calc` è diverso: BigQuery (quando si utilizza il dialetto SQL legacy) non utilizza i backtick (`) per l'offerta. Quindi pensa di far parte del nome e si tratta di un nuovo campo separato dal campo 'calc'. Basta rimuoverli o utilizzare le citazioni di BigQuery [e] - [calc]. O passare al dialetto SQL standard.

+0

Grazie Michael, i backtick erano davvero un problema. Il campo id mancante di GROUP BY è un buon punto, dato che questi dati funzionano bene in MySQL poiché i risultati sono noti per produrre lo stesso id per ogni raggruppamento (un po 'ridondante ma viene usato l'indice su id). L'ho cambiato come suggerito e ha funzionato. – LocalGeek

+0

Dovrebbe aggiungere, le prestazioni, ci sono voluti 75 secondi (dati 2,5 GB). Suddividere la query in un JOIN (producendo un set di dati), quindi eseguire GROUP BY richiede 20 secondi e quindi 15 secondi. Una scatola Linux con 32GB 2133Mhz RAM, 8GB usata da MySQL un processore AMD A10 piuttosto lento (7850K) con dati su un SSD Samsung 840 impiegava circa 2000 secondi per la query completa o per dividerli. – LocalGeek

+0

Performance-vice Credo che si possa trarre vantaggio dal filtraggio prima di JOIN (BigQuery non è abbastanza intelligente da farlo da solo): SELEZIONA ... DA (SELEZIONA .. DA nonstops WHERE lincat = 556) INTERNO ISCRIVITI OGNI (SELECT .. FROM WHERE MinusOne Lincat = 556) ON nonstops.lincat = minusone.lincat E nonstops.term = minusone.term GROUP BY nonstops.term, nonstops.lincat ORDER BY DESC calc – Michael