Kosten in BigQuery kontrollieren

Auf dieser Seite werden Best Practices zur Kontrolle der Kosten in BigQuery beschrieben.

Auf SELECT * verzichten

Best Practice: Fragen Sie nur die Spalten ab, die Sie benötigen.

Die Verwendung von SELECT * ist die kostenintensivste Methode zur Datenabfrage. Wenn Sie SELECT * verwenden, führt BigQuery einen vollständigen Scan aller Spalten in der Tabelle durch.

Wenn Sie mit Daten experimentieren oder Daten untersuchen, verwenden Sie anstelle von SELECT * eine der Datenvorschauoptionen.

Mit einer LIMIT-Klausel in einer SELECT *-Abfrage beeinflussen Sie nicht die Menge der gelesenen Daten. Sie bezahlen für alle Bytes der gesamten Tabelle. Außerdem wird die Abfrage Ihrem kostenlosen Kontingent angerechnet.

Fragen Sie stattdessen nur die Spalten ab, die Sie benötigen. Zum Beispiel verwenden Sie SELECT * EXCEPT, um eine oder mehrere Spalten aus den Ergebnissen auszuschließen.

Wenn Sie alle Spalten einer Tabelle abfragen möchten, aber jeweils nur eine Teilmenge der enthaltenen Daten einbeziehen möchten, könnte eine der folgenden Vorgehensweisen sinnvoll sein:

  • Die Ergebnisse in einer Zieltabelle erfassen und diese Tabelle abfragen
  • Ihre Tabellen nach Datum partitionieren und die relevante Partition abfragen, z. B. scannen Sie mit WHERE _PARTITIONDATE="2017-01-01" nur die Partition für den 1. Januar 2017

Daten mit Vorschauoptionen ansehen

Best Practice: Führen Sie keine Abfragen aus, um Tabellendaten zu erkunden oder eine Vorschau zu erstellen.

Wenn Sie mit Daten experimentieren oder diese erkunden, können Sie sie mit Tabellenvorschauoptionen kostenlos ansehen, ohne Ihr Kontingent zu nutzen.

In BigQuery stehen Ihnen die folgenden Optionen für eine Datenvorschau zur Verfügung:

  • Klicken Sie in der Cloud Console auf der Seite mit den Tabellendetails auf den Tab Vorschau, um die Daten abzufragen.
  • Verwenden Sie im bq-Befehlszeilentool den Befehl bq head und geben Sie die Anzahl der Zeilen für die Vorschau an.
  • Verwenden Sie in der API tabledata.list zum Abrufen von Tabellendaten aus einer bestimmten Gruppe von Zeilen.

Preise für Abfragen vorab ermitteln

Best Practice: Erstellen Sie vor dem Ausführen von Abfragen eine Vorschau, um die Kosten abzuschätzen.

Abfragen werden abhängig von der Anzahl der gelesenen Byte in Rechnung gestellt. Mit einer der folgenden Möglichkeiten können Sie die Kosten einer Abfrage vorab schätzen:

  • Mit der Abfragevalidierung in der Cloud Console
  • Mit dem Preisrechner der Google Cloud Platform
  • Durch Ausführen eines Probelaufs mit dem:
    • Flag --dry_run im bq-Befehlszeilentool
    • Parameter dryRun beim Senden eines Abfragejobs über die API

Abfragevalidierung verwenden

Wenn Sie eine Abfrage in der Cloud Console eingeben, überprüft die Abfragevalidierung die Abfragesyntax und liefert die geschätzte Anzahl der gelesenen Byte. Mit dieser Information können Sie im Preisrechner die Abfragekosten einschätzen.

Abfragevalidierung

Probelauf ausführen

So führen Sie einen Probelauf aus:

Console

Derzeit können Sie keinen Probelauf mit der Cloud Console ausführen.

bq

Geben Sie eine Abfrage wie die folgende zusammen mit dem Flag --dry_run ein:

bq query \
--use_legacy_sql=false \
--dry_run \
'SELECT
   COUNTRY,
   AIRPORT,
   IATA
 FROM
   `project_id`.dataset.airports
 LIMIT
   1000'
 

Dieser Befehl gibt folgende Antwort zurück:

Query successfully validated. Assuming the tables are not modified,
running this query will process 10918 bytes of data.

API

Für einen Probelauf über die API übergeben Sie einen Abfragejob, bei dem im JobConfiguration-Typ dryRun auf true gesetzt ist.

Go

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von Go in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Go API.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
)

// queryDryRun demonstrates issuing a dry run query to validate query structure and
// provide an estimate of the bytes scanned.
func queryDryRun(w io.Writer, projectID string) error {
	// projectID := "my-project-id"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	q := client.Query(`
	SELECT
		name,
		COUNT(*) as name_count
	FROM ` + "`bigquery-public-data.usa_names.usa_1910_2013`" + `
	WHERE state = 'WA'
	GROUP BY name`)
	q.DryRun = true
	// Location must match that of the dataset(s) referenced in the query.
	q.Location = "US"

	job, err := q.Run(ctx)
	if err != nil {
		return err
	}
	// Dry run is not asynchronous, so get the latest status and statistics.
	status := job.LastStatus()
	if err := status.Err(); err != nil {
		return err
	}
	fmt.Fprintf(w, "This query will process %d bytes\n", status.Statistics.TotalBytesProcessed)
	return nil
}

Java

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Java in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur BigQuery Java API.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.JobStatistics;
import com.google.cloud.bigquery.QueryJobConfiguration;

// Sample to run dry query on the table
public class QueryDryRun {

  public static void runQueryDryRun() {
    String query =
        "SELECT name, COUNT(*) as name_count "
            + "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
            + "WHERE state = 'WA' "
            + "GROUP BY name";
    queryDryRun(query);
  }

  public static void queryDryRun(String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query).setDryRun(true).setUseQueryCache(false).build();

      Job job = bigquery.create(JobInfo.of(queryConfig));
      JobStatistics.QueryStatistics statistics = job.getStatistics();

      System.out.println(
          "Query dry run performed successfully." + statistics.getTotalBytesProcessed());
    } catch (BigQueryException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Python

Für einen Probelauf mit der Python-Clientbibliothek legen Sie das Attribut QueryJobConfig.dry_run auf True fest. Client.query() gibt immer einen abgeschlossenen QueryJob zurück, wenn die Abfrage für einen Probelauf konfiguriert ist.

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Python in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur  Python API.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

job_config = bigquery.QueryJobConfig(dry_run=True, use_query_cache=False)

# Start the query, passing in the extra configuration.
query_job = client.query(
    (
        "SELECT name, COUNT(*) as name_count "
        "FROM `bigquery-public-data.usa_names.usa_1910_2013` "
        "WHERE state = 'WA' "
        "GROUP BY name"
    ),
    job_config=job_config,
)  # Make an API request.

# A dry run query completes immediately.
print("This query will process {} bytes.".format(query_job.total_bytes_processed))

Preisrechner verwenden

Wenn Sie die Abfragekosten im Google Cloud Platform-Preisrechner kalkulieren möchten, geben Sie die Anzahl der verarbeiteten Byte als MB, GB, TB oder PB ein. Falls Ihre Abfrage weniger als 1 TB verarbeitet, lautet die Schätzung 0 $, da BigQuery pro Monat 1 TB an On-Demand-Abfragen kostenlos verarbeitet.

Preisrechner

Abfragekosten durch Einschränkung der berechneten Byte begrenzen

Best Practice: Verwenden Sie die Einstellung für maximal berechnete Bytes, um die Abfragekosten zu begrenzen.

Sie können die Anzahl der berechneten Bytes für eine Abfrage mit der Einstellung für maximal berechnete Bytes begrenzen. Wenn Sie einen maximalen Wert für die berechneten Bytes festlegen, wird die Anzahl der Byte, die von der Abfrage gelesen werden, vor der Abfrageausführung geschätzt. Wenn die Anzahl der geschätzten Byte die Grenze überschreitet, schlägt die Abfrage fehl, ohne dass eine Gebühr anfällt.

Bei geclusterten Tabellen liegt die Schätzung der Anzahl der Byte, die für eine Abfrage in Rechnung gestellt werden, über eine Obergrenze und kann höher sein als die tatsächliche Anzahl von Byte, die nach Ausführen der Abfrage in Rechnung gestellt werden. In einigen Fällen kann die Abfrage einer geclusterten Tabelle dazu führen, dass eine Abfrage für eine geclusterte Tabelle fehlschlägt, obwohl die tatsächlich abgerechneten Byte nicht die in Rechnung gestellte maximale Menge überschreiten.

Wenn eine Abfrage aufgrund der Einstellung für maximal abgerechnete Bytes fehlschlägt, wird ein Fehler wie der folgende zurückgegeben:

Error: Query exceeded limit for bytes billed: 1000000. 10485760 or higher required.

So legen Sie die maximal berechneten Byte fest:

Console

  1. Klicken Sie im Abfrageeditor auf Mehr, klicken Sie auf Query settings (Abfrageeinstellungen) und dann auf Advanced options (Erweiterte Optionen).
  2. Geben Sie im Feld Maximale Menge abgerechneter Byte eine Ganzzahl ein.
  3. Klicken Sie auf Speichern.

bq

Führen Sie den Befehl bq query mit dem Flag --maximum_bytes_billed aus.

  bq query --maximum_bytes_billed=1000000 \
  --use_legacy_sql=false \
  'SELECT
     word
   FROM
     `bigquery-public-data`.samples.shakespeare'

API

Legen Sie das Attribut maximumBytesBilled in JobConfigurationQuery oder QueryRequest fest.

Geclusterte oder partitionierte Tabellen verwenden

Best Practice: Verwenden Sie Clustering und Partitionierung, um die gescannte Datenmenge zu reduzieren.

Clustering und Partitionierung können dazu beitragen, die von Abfragen verarbeitete Datenmenge zu reduzieren. Um die Anzahl der Partitionen zu begrenzen, die beim Abfragen von geclusterten oder partitionierten Tabellen gescannt werden, verwenden Sie einen Prädikatfilter.

Wenn Sie eine Abfrage für eine geclusterte Tabelle ausführen und die Abfrage einen Filter für die geclusterten Spalten enthält, verwendet BigQuery den Filterausdruck und die Blockmetadaten, um die von der Abfrage gescannten Blöcke zu bereinigen. Weitere Informationen finden Sie unter Geclusterte Tabellen abfragen.

Beim Abfragen partitionierter Tabellen werden Filter für die Partitionierungsspalte verwendet, um die Partitionen zu bereinigen und so die Abfragekosten zu reduzieren. Weitere Informationen finden Sie unter Partitionierte Tabellen abfragen.

LIMIT nicht für die Kostenkontrolle in nicht geclusterten Tabellen verwenden

Best Practice. Verwenden Sie für nicht geclusterte Tabellen die LIMIT-Klausel nicht zur Kostenkontrolle.

Bei nicht geclusterten Tabellen hat die Anwendung einer LIMIT-Klausel auf eine Abfrage keine Auswirkungen auf den Umfang der gelesenen Daten. Ihnen werden damit also alle von der Abfrage in der kompletten Tabelle gelesenen Byte in Rechnung gestellt, auch wenn die Abfrage nur eine Teilmenge zurückgibt. Mit einer geclusterten Tabelle kann dagegen mit der Klausel LIMIT die Anzahl der gescannten Byte reduziert werden.

Kosten in einem Dashboard einsehen und Audit-Logs abfragen

Best Practice: Erstellen Sie ein Dashboard, um Ihre Abrechnungsdaten einzusehen und die Nutzung von BigQuery anzupassen. Darüber hinaus können Sie Ihre Audit-Logs in BigQuery streamen, um die Nutzungsmuster zu analysieren.

Sie können Ihre Abrechnungsdaten nach BigQuery exportieren und sie in einem Tool wie Google Data Studio visualisieren. Eine Anleitung zum Erstellen eines Abrechnungs-Dashboards finden Sie unter GCP-Abrechnung mit BigQuery und Data Studio visualisieren.

Außerdem haben Sie die Möglichkeit, Ihre Audit-Logs in BigQuery zu streamen und sie auf Muster wie die Abfragekosten nach Nutzer zu analysieren.

Daten nach Datum partitionieren

Best Practice: Partitionieren Sie Ihre Tabellen nach Datum.

Partitionieren Sie Ihre BigQuery-Tabellen wenn möglich nach Datum. Durch die Partitionierung Ihrer Tabellen können Sie relevante Teilmengen von Daten abfragen, was die Leistung verbessert und die Kosten reduziert.

Verwenden Sie bei der Abfrage partitionierter Tabellen beispielsweise die Pseudospalte _PARTITIONTIME, um nach einem Datum oder Zeitraum zu filtern. Die Abfrage verarbeitet dann nur Daten in den Partitionen, die durch das Datum oder den Zeitraum angegeben sind.

Abfrageergebnisse in Phasen erfassen

Best Practice: Erfassen Sie Abfrageergebnisse nach Möglichkeit in separaten Phasen.

Wenn Sie eine große Abfrage mit mehreren Phasen erstellen, liest BigQuery jedes Mal, wenn Sie diese ausführen, alle Daten, auf die sich die Abfrage bezieht. Bei jeder Ausführung der Abfrage werden Ihnen alle gelesenen Daten in Rechnung gestellt.

Teilen Sie stattdessen Ihre Abfrage in Phasen auf, wobei jede Phase ihre Abfrageergebnisse in eine Zieltabelle schreibt. Durch das Abfragen der kleineren Zieltabelle verringert sich die Menge der gelesenen Daten und die Kosten sinken. Der finanzielle Aufwand für die Speicherung der erfassten Ergebnisse ist deutlich geringer als der für die Verarbeitung großer Datenmengen.

Kosten für große Ergebnissets berücksichtigen

Best Practice: Wenn Sie große Abfrageergebnisse in eine Zieltabelle schreiben, verwenden Sie am besten die Standardablaufzeit von Tabellen, um die Daten zu löschen, sobald sie nicht mehr benötigt werden.

Das Aufbewahren großer Ergebnissets im BigQuery-Speicher ist teuer. Wenn Sie die Ergebnisse nicht dauerhaft benötigen, sollten Sie die Daten durch Festlegen der Standardablaufzeit von Tabellen automatisch löschen lassen.

Weitere Informationen finden Sie unter Speicherpreise.

Streaming-Insert-Anweisungen mit Vorsicht verwenden

Best Practice: Verwenden Sie Streaming-Insert-Anweisungen nur, wenn Ihre Daten sofort verfügbar sein müssen.

Es kostet nichts, Daten in BigQuery zu laden. Für das Streamen von Daten in BigQuery fallen jedoch Kosten an. Wenn Ihre Daten nicht sofort verfügbar sein müssen, laden Sie diese, anstatt sie zu streamen.