# BigQuery

## Vad det är

BigQuery är en hanterad tjänst för analys med SQL i Google Cloud: det finns ingen server att sätta
upp, tabellerna lagras kolumn för kolumn, och varje databasfråga betalas antingen efter de byte som
den läser eller ur beräkningskapacitet som har reserverats i förväg. Tjänsten säljs och söks också
efter som Google BigQuery, och dess SQL-dialekt heter GoogleSQL, som följer ANSI-standarden och
lägger till egna funktioner.

Designen vilar på att hålla lagring och beräkning isär. Tabellerna ligger i Googles lagringslager,
och en fråga lånar beräkningskraft så länge den körs. Eftersom varje kolumn lagras för sig läser en
fråga som nämner tre kolumner i en tabell med femtio bara de tre och lämnar resten på disken. Att
trimma prestandan ser därför annorlunda ut än på en PostgreSQL-server. I stället för att utforma
B-tree-index och dimensionera minnet handlar arbetet om tabellens form, med partitionering och
klustring: en tabell kan delas upp efter en kolumn med datum eller tidsstämpel, efter tidpunkten för
inläsningen eller efter ett heltalsintervall, och klustras på upp till fyra kolumner så att rader
som hör ihop delar lagringsblock.

BigQuery hör till familjen analysdatalager, och de produkter den oftast vägs mot är Snowflake och
Amazon Redshift, plus möjligheten att behålla analysen i den transaktionsdatabas som företaget redan
kör. Den är byggd för frågor som sveper över miljontals eller miljarder rader och returnerar en
handfull summor. De uppslag och uppdateringar av enskilda rader som en applikation gör vid varje
förfrågan hör hemma i en databas som PostgreSQL eller SQL Server, och ett vanligt upplägg kör båda,
med en datapipeline som för data från den ena till den andra.

## Varför det spelar roll

Beslutet som BigQuery ställer ett team inför är hur det vill betala för analys. Räkningen följer de
frågor som folk skriver, inte storleken på en maskin som någon en gång valde, och det skär åt båda
hållen.

Med prissättning på begäran (on-demand) debiteras varje fråga för de byte som den bearbetar. Det
passar oregelbundet arbete: ett team som kör några tunga rapporter i veckan betalar för de
rapporterna och för inget däremellan, utan någon server som står på tomgång över natten. Det sätter
också ett pris på en slarvig fråga. En `SELECT *` över ett års sensoravläsningar kostar lika mycket
oavsett om analytikern ville ha en rad eller alla. Kapacitetsprissättning ersätter det med slots,
enheter av beräkningskraft som köps genom reservationer, vilket gör räkningen till en siffra som är
känd i förväg och gör tung, jämn användning billigare att planera för. Ett projekt kan byta mellan
de två modellerna, så det första valet går att ompröva när den verkliga användningen syns.

Lagringen har sina egna regler. En tabell eller partition som har lämnats oförändrad i 90 dagar i
följd går över till priset för långtidslagring, som är 50 % lägre, utan att någon flyttar den. Varje
dataset debiteras antingen efter den logiska, okomprimerade storleken på sina data eller efter den
fysiska, komprimerade, och för data som komprimeras väl kan den andra modellen vara den billigare.

Tre saker förtjänar eftertanke innan man skriver på. Platsen för ett dataset, en enskild region
eller multiregionen US eller EU, bestäms när det skapas och ligger sedan fast, så den är ett beslut
om regelefterlevnad som fattas den första dagen. Dialekten, kommandoradsverktyget `bq` och
klientbiblioteken är Googles egna, så frågor flyttar till ett annat analysdatalager med ändringar
snarare än oförändrade; själva datan tar sig lätt ut, eftersom tabeller kan exporteras till CSV,
Avro och Parquet. Och frågan om rekrytering är mildare än den ser ut: analytiker som kan SQL är
produktiva inom några dagar, medan den ovanligare färdigheten är att läsa en fråga i byte lika väl
som i rader.

Så när är BigQuery rätt val? När data kommer i stora volymer som mest läggs till, t.ex. händelser,
loggar eller mätaravläsningar, när frågorna som ställs till dem ändras från vecka till vecka, och
när teamet helst slipper driva databasservrar för analys. För data som en enda PostgreSQL-server
rymmer utan besvär lägger ett analysdatalager till ett andra system, en andra räkning och en
datapipeline mellan de två. Skälen för det växer med volymen och med antalet personer som ställer
frågor.

## Så ser det ut i praktiken

Ett bestånd med över 100 databaser, fördelade på PostgreSQL, Microsoft SQL Server och Google
BigQuery, höll mest geografiska data och tidsseriedata: koordinater, sensoravläsningar, loggar och
mätvärden i realtid. I rollen som databasingenjör, mellan 2022 och 2024, lades de storskaliga
tidsseriedata i BigQuery,
[i tabeller som var tidspartitionerade och klustrade](/sv/portfolio/architected-created-and-managed-100-postgresql-ms-sql-12/),
med komprimering och kolumnlagring för att hålla nere lagringskostnaderna och snabba upp
skanningarna. Partitionerade och klustrade skanningar i BigQuery, tillsammans med indexering,
materialiserade vyer och cachning i hela beståndet, kortade svarstiderna för frågor mot GIS- och
tidsseriedata med 40–60 %.

I en datapipeline för geografiska data som hade blivit långsam analyserades först SQL-koden och
datamodellerna i PostgreSQL, MS SQL och Google Cloud BigQuery, i rollen som dataingenjör under samma
år. Analysen blottlade svag indexering, ineffektiva frågor och saknade integritetsvillkor. Varje
motor fick sedan det verktyg den har: B-tree- och GiST-index i PostgreSQL, filtrerade index i MS SQL
och
[klustring i BigQuery](/sv/portfolio/accelerated-geographical-data-pipeline-performance-by-50x-by-5/),
tillsammans med normaliserade datamodeller, partitionering och omskrivna frågor. Datapipelinen som
helhet blev 50 gånger snabbare.

Och på data från smarta elmätare i flera regioner
[togs över 500 analysrapporter fram i ren SQL](/sv/portfolio/released-500-electricity-and-gis-data-analysis-reports-11/)
mot PostgreSQL och BigQuery, i rollen som dataanalytiker, med CTE:er, fönsterfunktioner, underfrågor
och geospatiala joins över mätar-ID:n, tidsstämplar, koordinater och miljömetadata. Varje rapport
levererades med kommenterad SQL, så att en kollega kunde köra om och granska den, och med
anteckningar om kända datakvalitetsproblem som saknade GPS-koordinater och korrupta mätvärden.
Rapporterna blev ett standardunderlag på flera avdelningar och bidrog till 10–15 % effektivare
operativ planering.

I alla tre fallen arbetade BigQuery bredvid PostgreSQL snarare än i dess ställe, och varje motor
fick det arbete som den gör bäst.

## Var det går fel

**En fråga med `LIMIT 10` debiteras för hela tabellen.** På en tabell utan klustring begränsar
`LIMIT` resultatet, inte de byte som läses, och `SELECT *` läser varje kolumn som finns. En snabb
titt på datan blir en fullständig skanning. Namnge de kolumner som frågan behöver, och använd
konsolens förhandsvisning av tabellen eller `bq head` för en blick på några exempelrader, vilket
inte kostar något.

**En partitionerad tabell skannas ändå från början till slut.** Partitioner hoppas bara över när
filtret på partitioneringskolumnen är en konstant som motorn kan utvärdera innan den läser. Att
jämföra kolumnen med resultatet av en underfråga, svepa in den i en funktion eller räkna på den
skickar frågan genom varje partition. Två skydd hjälper. En tabell kan kräva ett partitionsfilter,
så att en fråga utan ett användbart filter stoppas med ett fel i stället för att köras. Och en
torrkörning (dry run) rapporterar hur många byte en fråga skulle bearbeta, utan att köra den eller
ta betalt för den:

```sh
bq query --use_legacy_sql=false --dry_run \
  'SELECT meter_id, kwh
   FROM energy.readings
   WHERE reading_date = DATE "2026-10-01"'
```

**Klustring läggs till och mängden lästa byte rör sig knappt.** Klustring sorterar lagringsblock
efter upp till fyra kolumner i ordning, och ordningen spelar roll: en tabell som är klustrad efter
orderdatum, land och status är inte organiserad för ett filter på enbart land och status. Tabeller
under 64 MB vinner lite på det, och på en klustrad tabell blir antalet byte som faktiskt skannas
känt först när frågan är klar. Ordna klustringskolumnerna på det sätt som frågorna filtrerar. Där
kostnaden måste ha ett tak innan något körs, lita på partitionering, vars beskärning en torrkörning
redan räknar med, och sätt ett högsta antal debiterade byte (maximum bytes billed), så att en fråga
över gränsen stoppas innan den debiteras.

**En fråga som gör en join mellan två dataset avvisas.** Varje dataset ligger på en plats, och en
fråga körs på en plats, så varje dataset som den rör måste dela den. Team som låter varje projekt ta
sin egen standardplats får tabeller som bara kan förenas efter att en av dem har kopierats över.
Välj platsen en gång, för regelefterlevnadens skull och efter var datan kommer ifrån, och skapa
varje dataset där med avsikt.

## Läs mer

- [BigQuery overview](https://cloud.google.com/bigquery/docs/introduction) — Googles egen
  beskrivning av tjänsten, dess separata lager för lagring och beräkning och det som sköts åt
  användaren.
- [Introduction to partitioned tables](https://docs.cloud.google.com/bigquery/docs/partitioned-tables)
  — typerna av partitionering, deras upplösning och deras gränser.
- [Query partitioned tables](https://docs.cloud.google.com/bigquery/docs/querying-partitioned-tables)
  — vilka filter som beskär partitioner och vilka som skickar en fråga genom alla.
- [Introduction to clustered tables](https://docs.cloud.google.com/bigquery/docs/clustered-tables) —
  hur kolumnordningen styr beskärningen av block, och vad det betyder för kostnadsuppskattningar.
- [Estimate and control costs](https://docs.cloud.google.com/bigquery/docs/best-practices-costs) —
  torrkörningar, högsta antal debiterade byte och de kostnadsfria sätten att förhandsvisa en tabell.
- [BigQuery locations](https://docs.cloud.google.com/bigquery/docs/locations) — regioner,
  multiregioner och reglerna för frågor som rör mer än ett dataset.

<https://engineer.company/sv/glossary/bigquery/>
