Mengoptimalkan komputasi kueri

Dokumen ini memberikan praktik terbaik untuk mengoptimalkan performa kueri Anda.

Setelah kueri selesai, Anda dapat melihat paket kueri di konsol Google Cloud. Anda juga dapat meminta detail eksekusi dengan menggunakan tampilan INFORMATION_SCHEMA.JOBS* atau metode REST API jobs.get.

Paket kueri mencakup detail tentang tahapan dan langkah kueri. Detail ini dapat membantu Anda mengidentifikasi cara meningkatkan performa kueri. Misalnya, jika Anda melihat tahap yang menulis lebih banyak output daripada tahap lain, ini mungkin berarti Anda perlu memfilter lebih awal dalam kueri.

Untuk mempelajari lebih lanjut paket kueri dan melihat contoh bagaimana informasi paket kueri dapat membantu Anda meningkatkan performa kueri, lihat Mendapatkan insight performa kueri. Setelah memahami insight performa kueri, Anda dapat mengoptimalkan kueri lebih lanjut dengan melakukan tugas berikut:

Mengurangi data yang diproses

Anda dapat mengurangi data yang perlu diproses menggunakan opsi yang dijelaskan di bagian berikut.

MenghindarinSELECT *

Praktik terbaik: Kontrol proyeksi dengan membuat kueri untuk kolom yang Anda butuhkan saja.

Proyeksi mengacu pada jumlah kolom yang dibaca oleh kueri Anda. Memproyeksikan kolom berlebih akan menimbulkan I/O dan materialisasi (hasil penulisan) tambahan (yang terbuang).

  • Gunakan opsi pratinjau data. Jika Anda bereksperimen dengan data atau mengeksplorasi data, gunakan salah satu opsi pratinjau data, bukan SELECT *.
  • Buat kueri untuk kolom tertentu. Menerapkan klausa LIMIT ke kueri SELECT * tidak memengaruhi jumlah data yang dibaca. Anda akan dikenai biaya untuk membaca semua byte di seluruh tabel, dan kueri akan mengurangi kuota paket gratis Anda. Sebagai gantinya, hanya buat kueri untuk kolom yang Anda perlukan. Misalnya, gunakan SELECT * EXCEPT untuk mengecualikan satu atau beberapa kolom dari hasil.
  • Gunakan tabel berpartisi. Jika Anda memang memerlukan kueri terhadap setiap kolom dalam tabel, tetapi hanya terhadap subset data, pertimbangkan:

  • Gunakan SELECT * EXCEPT. Membuat kueri subset data atau menggunakan SELECT * EXCEPT dapat mengurangi jumlah data yang dibaca oleh kueri secara signifikan. Selain hemat biaya, performa juga ditingkatkan dengan mengurangi jumlah I/O data dan jumlah materialisasi yang diperlukan untuk hasil kueri.

    SELECT * EXCEPT (col1, col2, col5)
    FROM mydataset.newtable
    

Menghindari tabel karakter pengganti yang berlebihan

Praktik terbaik: Saat membuat kueri tabel karakter pengganti, Anda harus menggunakan awalan yang paling terperinci.

Gunakan karakter pengganti untuk membuat kueri beberapa tabel dengan menggunakan pernyataan SQL yang ringkas. Tabel karakter pengganti adalah gabungan tabel yang cocok dengan ekspresi karakter pengganti. Tabel karakter pengganti berguna jika set data Anda berisi resource berikut:

  • Beberapa tabel yang bernama mirip dengan skema yang kompatibel
  • Tabel dengan sharding

Saat membuat kueri tabel karakter pengganti, tentukan karakter pengganti (*) setelah awalan tabel yang umum. Misalnya, FROM bigquery-public-data.noaa_gsod.gsod194* membuat kueri semua tabel dari tahun 1940-an.

Awalan yang lebih terperinci berperforma lebih baik daripada awalan yang lebih pendek. Misalnya, FROM bigquery-public-data.noaa_gsod.gsod194* berperforma lebih baik daripada FROM bigquery-public-data.noaa_gsod.* karena lebih sedikit tabel yang cocok dengan karakter pengganti.

Menghindari tabel yang di-sharding menurut tanggal

Praktik terbaik: Jangan gunakan tabel yang di-sharding menurut tanggal (juga disebut tabel bernama tanggal) sebagai pengganti tabel yang dipartisi oleh waktu.

Tabel berpartisi berperforma lebih baik daripada tabel bernama tanggal. Jika Anda membuat tabel yang di-sharding menurut tanggal, BigQuery harus menyimpan salinan skema dan metadata untuk setiap tabel bernama tanggal. Selain itu, saat tabel bernama tanggal digunakan, BigQuery mungkin diperlukan untuk memverifikasi izin setiap tabel yang dikueri. Praktik ini juga menambah overhead kueri dan memengaruhi performa kueri.

Menghindari melakukan sharding tabel yang berlebihan

Praktik terbaik: Hindari membuat terlalu banyak sharding tabel. Jika Anda melakukan sharding tabel berdasarkan tanggal, gunakan tabel yang dipartisi oleh waktu.

Sharding tabel mengacu pada membagi set data besar ke dalam tabel terpisah dan menambahkan akhiran ke setiap nama tabel. Jika Anda melakukan sharding tabel berdasarkan tanggal, gunakan tabel yang dipartisi waktu sebagai gantinya.

Karena biaya penyimpanan BigQuery yang rendah, Anda tidak perlu mengoptimalkan tabel untuk biaya seperti yang Anda lakukan di sistem database relasional. Membuat shard tabel dalam jumlah besar akan menyebabkan dampak performa yang lebih besar daripada manfaat biayanya.

Tabel dengan sharding memerlukan BigQuery untuk mempertahankan skema, metadata, dan izin untuk setiap shard. Karena overhead tambahan yang diperlukan untuk mempertahankan informasi pada setiap shard, melakukan sharding tabel yang berlebihan dapat memengaruhi performa kueri.

Jumlah dan sumber data yang dibaca oleh kueri dapat memengaruhi performa dan biaya kueri.

Memangkas kueri yang dipruning

Praktik terbaik: Saat membuat kueri tabel yang dipartisi, untuk memfilter dengan partisi pada tabel yang dipartisi, gunakan kolom berikut:

  • Untuk tabel berpartisi waktu penyerapan, gunakan kolom pseudo _PARTITIONTIME
  • Untuk tabel yang dipartisi seperti berbasis kolom satuan waktu dan rentang bilangan bulat, gunakan kolom partisi.

Untuk tabel yang dipartisi unit waktu, memfilter data dengan _PARTITIONTIME atau kolom partisi memungkinkan Anda menentukan tanggal atau rentang tanggal. Misalnya, klausa WHERE berikut menggunakan kolom pseudo _PARTITIONTIME untuk menentukan partisi antara 1 Januari 2016 dan 31 Januari 2016:

WHERE _PARTITIONTIME
BETWEEN TIMESTAMP("20160101")
AND TIMESTAMP("20160131")

Kueri hanya memproses data dalam partisi yang ditunjukkan oleh rentang tanggal. Memfilter partisi akan meningkatkan performa kueri dan mengurangi biaya.

Kurangi data sebelum menggunakan JOIN

Praktik terbaik: Kurangi jumlah data yang diproses sebelum klausa JOIN dengan melakukan agregasi.

Penggunaan klausa GROUP BY dengan fungsi agregat memerlukan banyak komputasi, karena jenis kueri ini menggunakan shuffle ini. Karena kueri ini menggunakan banyak komputasi, Anda harus menggunakan klausa GROUP BY hanya jika diperlukan.

Untuk kueri dengan GROUP BY dan JOIN, lakukan agregasi lebih awal di kueri untuk mengurangi jumlah data yang diproses. Misalnya, kueri berikut menjalankan JOIN pada dua tabel besar tanpa pemfilteran terlebih dahulu:

WITH
  users_posts AS (
  SELECT *
  FROM
    `bigquery-public-data`.stackoverflow.comments AS c
  JOIN
    `bigquery-public-data`.stackoverflow.users AS u
  ON
    c.user_id = u.id
  )
SELECT
  user_id,
  ANY_VALUE(display_name) AS display_name,
  ANY_VALUE(reputation) AS reputation,
  COUNT(text) AS comments_count
FROM users_posts
GROUP BY user_id
ORDER BY comments_count DESC
LIMIT 20;

Kueri ini telah menggabungkan jumlah komentar sehingga mengurangi jumlah data yang dibaca untuk JOIN:

WITH
  comments AS (
  SELECT
    user_id,
    COUNT(text) AS comments_count
  FROM
    `bigquery-public-data`.stackoverflow.comments
  WHERE
    user_id IS NOT NULL
  GROUP BY user_id
  ORDER BY comments_count DESC
  LIMIT 20
  )
SELECT
  user_id,
  display_name,
  reputation,
  comments_count
FROM comments
JOIN
  `bigquery-public-data`.stackoverflow.users AS u
ON
  user_id = u.id
ORDER BY comments_count DESC;

Menggunakan klausa WHERE

Praktik terbaik: Gunakan klausa WHERE untuk membatasi jumlah data yang ditampilkan oleh kueri. Jika memungkinkan, gunakan kolom BOOL, INT, FLOAT, atau DATE dalam klausa WHERE.

Operasi di kolom BOOL, INT, FLOAT, dan DATE biasanya lebih cepat daripada operasi pada kolom STRING atau BYTE. Jika memungkinkan, gunakan kolom yang menggunakan salah satu jenis data ini dalam klausa WHERE untuk mengurangi jumlah data yang ditampilkan oleh kueri.

Mengoptimalkan operasi kueri

Anda dapat mengoptimalkan operasi kueri menggunakan opsi yang dijelaskan di bagian berikut.

Menghindari mengubah data berulang kali

Praktik terbaik: Jika Anda menggunakan SQL untuk melakukan operasi ETL, hindari situasi saat Anda berulang kali mengubah data yang sama.

Misalnya, jika Anda menggunakan SQL untuk memangkas string atau mengekstrak data dengan menggunakan ekspresi reguler, akan lebih efektif untuk merealisasikan hasil yang diubah dalam tabel tujuan. Fungsi seperti ekspresi reguler memerlukan komputasi tambahan. Membuat kueri tabel tujuan tanpa overhead transformasi tambahan akan jauh lebih efisien.

Menghindari beberapa evaluasi CTE yang sama

Praktik terbaik: Gunakan bahasa prosedur, variabel, tabel sementara, dan tabel yang akan berakhir secara otomatis untuk mempertahankan penghitungan dan menggunakannya nanti di kueri.

Jika kueri Anda berisi ekspresi tabel umum (CTE) yang digunakan di beberapa tempat dalam kueri, kueri tersebut mungkin akan dievaluasi setiap kali direferensikan. Pengoptimal kueri mencoba mendeteksi bagian-bagian kueri yang hanya dapat dieksekusi satu kali, tetapi hal ini mungkin tidak selalu dapat dilakukan. Akibatnya, penggunaan CTE mungkin tidak membantu mengurangi kompleksitas kueri internal dan konsumsi resource.

Anda dapat menyimpan hasil CTE dalam variabel skalar atau tabel sementara, bergantung pada data yang ditampilkan CTE.

Menghindari penggabungan dan subkueri berulang

Praktik terbaik: Hindari menggabungkan tabel yang sama dan menggunakan subkueri yang sama berulang kali.

Alih-alih berulang kali menggabungkan data, mungkin akan lebih efektif bagi Anda untuk menggunakan data berulang bertingkat untuk mewakili hubungan. Data berulang bertingkat menghemat dampak performa dari bandwidth komunikasi yang diperlukan gabungan. Hal ini juga menghemat biaya I/O yang Anda timbulkan dengan membaca dan menulis data yang sama berulang kali. Untuk informasi selengkapnya, lihat menggunakan kolom bertingkat dan berulang.

Demikian pula, mengulangi subkueri yang sama akan memengaruhi performa melalui pemrosesan kueri yang berulang. Jika Anda menggunakan subkueri yang sama di beberapa kueri, pertimbangkan untuk mewujudkan hasil subkueri dalam tabel. Kemudian, gunakan data terwujud dalam kueri Anda.

Mewujudkan hasil subkueri Anda akan meningkatkan performa dan mengurangi jumlah keseluruhan data yang dibaca dan ditulis oleh BigQuery. Biaya kecil untuk menyimpan data terwujud lebih besar daripada dampak performa dari pemrosesan kueri dan I/O berulang.

Mengoptimalkan pola penggabungan

Praktik terbaik: Untuk kueri yang menggabungkan data dari beberapa tabel, optimalkan pola gabungan Anda dengan memulai dari tabel terbesar.

Saat Anda membuat kueri menggunakan klausa JOIN, perhatikan urutan penggabungan data. Pengoptimal kueri GoogleSQL menentukan tabel mana yang harus berada di sisi gabungan mana. Sebagai praktik terbaik, tempatkan tabel dengan jumlah baris terbesar terlebih dahulu, diikuti oleh tabel dengan baris paling sedikit, lalu tempatkan tabel yang tersisa dengan mengurangi ukurannya.

Jika Anda memiliki tabel besar di sisi kiri JOIN dan tabel kecil di sisi kanan JOIN, gabungan siaran akan dibuat. Sambungan siaran mengirimkan semua data dalam tabel yang lebih kecil ke setiap slot yang memproses tabel yang lebih besar. Sebaiknya lakukan penggabungan siaran terlebih dahulu.

Untuk melihat ukuran tabel di JOIN, lihat Mendapatkan informasi tentang tabel.

Mengoptimalkan klausa ORDER BY

Praktik terbaik: Saat menggunakan klausa ORDER BY, pastikan Anda mengikuti praktik terbaik:

  • Gunakan ORDER BY di kueri terluar atau dalam klausa jendela. Kirim operasi kompleks ke akhir kueri. Menempatkan klausa ORDER BY di tengah kueri akan sangat memengaruhi performa, kecuali jika sedang digunakan dalam fungsi jendela.

    Teknik lain untuk mengurutkan kueri adalah mendorong operasi yang kompleks, seperti ekspresi reguler dan fungsi matematika, ke akhir kueri. Teknik ini mengurangi data yang akan diproses sebelum operasi yang kompleks dilakukan.

  • Gunakan klausa LIMIT. Jika Anda mengurutkan nilai dalam jumlah yang sangat besar tetapi tidak perlu menampilkan semuanya, gunakan klausa LIMIT. Misalnya, kueri berikut mengurutkan kumpulan hasil yang sangat besar dan menampilkan error Resources exceeded. Kueri diurutkan berdasarkan kolom title di mytable. Kolom title berisi jutaan nilai.

    SELECT
    title
    FROM
    `my-project.mydataset.mytable`
    ORDER BY
    title;
    

    Untuk menghapus error, gunakan kueri seperti berikut:

    SELECT
    title
    FROM
    `my-project.mydataset.mytable`
    ORDER BY
    title DESC
    LIMIT
    1000;
    
  • Gunakan fungsi jendela. Jika Anda mengurutkan nilai dalam jumlah yang sangat besar, gunakan fungsi jendela, dan batasi data sebelum memanggil fungsi jendela. Misalnya, kueri berikut mencantumkan sepuluh pengguna Stack Overflow terlama dan peringkat mereka, dengan akun terlama yang memiliki peringkat terendah:

    SELECT
    id,
    reputation,
    creation_date,
    DENSE_RANK() OVER (ORDER BY creation_date) AS user_rank
    FROM bigquery-public-data.stackoverflow.users
    ORDER BY user_rank ASC
    LIMIT 10;
    

    Kueri ini membutuhkan waktu sekitar 15 detik untuk dijalankan. Kueri ini menggunakan LIMIT di akhir kueri, tetapi tidak di fungsi jendela DENSE_RANK() OVER. Karena itu, kueri mengharuskan semua data diurutkan pada satu worker node.

    Sebagai gantinya, Anda harus membatasi set data sebelum menghitung fungsi jendela untuk meningkatkan performa:

    WITH users AS (
    SELECT
    id,
    reputation,
    creation_date,
    FROM bigquery-public-data.stackoverflow.users
    ORDER BY creation_date ASC
    LIMIT 10)
    SELECT
    id,
    reputation,
    creation_date,
    DENSE_RANK() OVER (ORDER BY creation_date) AS user_rank
    FROM users
    ORDER BY user_rank;
    

    Kueri ini membutuhkan waktu sekitar 2 detik untuk dijalankan, sekaligus menampilkan hasil yang sama seperti kueri sebelumnya.

    Salah satu hal yang perlu diwaspadai adalah fungsi DENSE_RANK() akan mengurutkan data di dalam beberapa tahun. Jadi, untuk menentukan peringkat data yang mencakup beberapa tahun, kueri ini tidak memberikan hasil yang identik.

Memisahkan kueri kompleks menjadi kueri yang lebih kecil

Praktik terbaik: Manfaatkan kemampuan kueri multi-pernyataan dan prosedur tersimpan untuk melakukan komputasi yang dirancang sebagai satu kueri yang kompleks sebagai beberapa kueri yang lebih kecil dan lebih sederhana.

Kueri kompleks, fungsi REGEX, dan subkueri atau gabungan berlapis dapat menjadi lambat dan memerlukan banyak resource untuk dijalankan. Mencoba memasukkan semua komputasi ke dalam satu pernyataan SELECT besar, misalnya untuk menjadikannya sebuah tampilan, terkadang merupakan anti-pola, dan dapat menghasilkan kueri yang lambat dan membutuhkan banyak resource. Dalam kasus yang ekstrem, paket kueri internal menjadi sangat kompleks sehingga BigQuery tidak dapat menjalankannya.

Memisahkan kueri yang kompleks memungkinkan terwujudnya hasil menengah dalam variabel atau tabel sementara. Anda kemudian bisa menggunakan hasil antara ini di bagian lain dari kueri. Makin berguna saat hasil tersebut diperlukan di lebih dari satu tempat kueri.

Sering kali hal ini memungkinkan Anda untuk mengekspresikan intent sebenarnya dari bagian kueri dengan tabel sementara menjadi titik materialisasi data.

Menggunakan kolom bertingkat dan berulang

Untuk mengetahui informasi tentang cara melakukan denormalisasi penyimpanan data menggunakan kolom bertingkat dan berulang, lihat Menggunakan kolom bertingkat dan berulang.

Menggunakan jenis data INT64 dalam penggabungan

Praktik terbaik: Gunakan jenis data INT64 dalam gabungan, bukan jenis data STRING untuk mengurangi biaya dan meningkatkan performa perbandingan.

BigQuery tidak mengindeks kunci utama seperti database tradisional, jadi semakin lebar kolom join, semakin lama perbandingannya. Oleh karena itu, penggunaan jenis data INT64 dalam join akan lebih murah dan lebih efisien daripada menggunakan jenis data STRING.

Mengurangi output kueri

Anda dapat mengurangi output kueri menggunakan opsi yang dijelaskan di bagian berikut ini.

Mewujudkan kumpulan hasil yang besar

Praktik terbaik: Pertimbangkan untuk mewujudkan kumpulan hasil besar ke tabel tujuan. Menulis kumpulan hasil yang besar dapat memengaruhi performa dan biaya.

BigQuery membatasi hasil yang di-cache hingga sekitar 10 GB terkompresi. Kueri yang menampilkan hasil lebih besar akan melampaui batas ini dan sering menyebabkan error berikut: Response too large.

Error ini sering terjadi saat Anda memilih sejumlah besar kolom dari tabel yang berisi data dalam jumlah yang cukup besar. Masalah saat menulis hasil yang di-cache juga dapat terjadi dalam kueri gaya ETL yang menormalisasi data tanpa pengurangan atau agregasi.

Anda dapat mengatasi batas ukuran hasil yang di-cache menggunakan opsi berikut:

  • Menggunakan filter untuk membatasi kumpulan hasil
  • Gunakan klausa LIMIT untuk mengurangi kumpulan hasil, terutama jika Anda menggunakan klausa ORDER BY
  • Menulis data output ke tabel tujuan

Anda dapat menjelajahi hasil menggunakan BigQuery REST API. Untuk mengetahui informasi selengkapnya, lihat Paging melalui data tabel.

Menggunakan BI Engine

Untuk lebih mempercepat kueri SQL Anda dengan meng-cache data yang paling sering Anda gunakan, pertimbangkan untuk menambahkan reservasi BI Engine ke project tempat kueri dikomputasi. BigQuery BI Engine menggunakan mesin kueri vektor untuk mempercepat performa kueri SELECT.

Menghindari pola anti-SQL

Praktik terbaik berikut memberikan panduan untuk menghindari antipola kueri yang memengaruhi performa di BigQuery.

Menghindari self join

Praktik terbaik: Daripada menggunakan penggabungan mandiri, gunakan fungsi window (analytic) atau operator PIVOT.

Biasanya, self-join digunakan untuk menghitung hubungan yang bergantung pada baris. Hasil penggunaan self-join adalah berpotensi menghitung pangkat baris output. Peningkatan data output ini dapat menyebabkan performa yang buruk.

Menghindari cross join

Praktik terbaik: Hindari join yang menghasilkan lebih banyak output daripada input. Jika CROSS JOIN diperlukan, gabungkan data Anda terlebih dahulu.

Cross join adalah kueri dengan setiap baris dari tabel pertama digabungkan ke setiap baris dalam tabel kedua, dengan kunci non-unik di kedua sisi. Output kasus terburuk adalah jumlah baris dalam tabel kiri dikalikan dengan jumlah baris dalam tabel kanan. Dalam kasus yang ekstrem, kueri mungkin tidak selesai.

Jika tugas kueri selesai, penjelasan paket kueri akan menampilkan baris output versus baris input. Anda dapat mengonfirmasi Cartesian product dengan mengubah kueri untuk mencetak jumlah baris di setiap sisi klausa JOIN, yang dikelompokkan berdasarkan kunci gabungan.

Untuk menghindari masalah performa terkait join yang menghasilkan lebih banyak output daripada input:

  • Gunakan klausa GROUP BY untuk menggabungkan data sebelumnya.
  • Gunakan fungsi jendela. Fungsi jendela sering kali lebih efisien dibandingkan menggunakan cross join. Untuk mengetahui informasi selengkapnya, lihat fungsi jendela.

Menghindari pernyataan DML yang mengupdate atau menyisipkan baris tunggal

Praktik terbaik: Hindari pernyataan DML yang memperbarui atau menyisipkan satu baris. Gabungkan pembaruan dan sisipan Anda dalam batch.

Menggunakan pernyataan DML spesifik per titik adalah upaya untuk memperlakukan BigQuery seperti sistem Pemrosesan Transaksi Online (OLTP). BigQuery berfokus pada Online Analytical Processing (OLAP) dengan menggunakan pemindaian tabel, alih-alih pencarian titik. Jika Anda memerlukan perilaku seperti OLTP (update atau penyisipan baris tunggal), pertimbangkan database yang didesain untuk mendukung kasus penggunaan OLTP seperti Cloud SQL.

Pernyataan DML BigQuery ditujukan untuk update massal. Pernyataan DML UPDATE dan DELETE di BigQuery berorientasi pada penulisan ulang data secara berkala, bukan mutasi baris tunggal. Pernyataan DML INSERT dimaksudkan untuk digunakan secara hemat. Sisipkan menggunakan quotas modifikasi yang sama dengan tugas pemuatan. Jika kasus penggunaan Anda sering melibatkan penyisipan baris tunggal, pertimbangkan untuk melakukan streaming data Anda.

Jika mengelompokkan pernyataan UPDATE menghasilkan banyak tule dalam kueri yang sangat panjang, Anda mungkin akan mendekati batas panjang kueri sebesar 256 KB. Untuk mengatasi batas panjang kueri, pertimbangkan apakah pembaruan dapat ditangani berdasarkan kriteria logis, bukan serangkaian penggantian tuple langsung.

Misalnya, Anda dapat memuat kumpulan data pengganti ke tabel lain, lalu menulis pernyataan DML untuk memperbarui semua nilai dalam tabel asli jika kolom yang tidak diperbarui cocok. Misalnya, jika data asli berada dalam tabel t dan pembaruannya dilakukan dalam tabel u, kueri akan terlihat seperti berikut:

UPDATE
  dataset.t t
SET
  my_column = u.my_column
FROM
  dataset.u u
WHERE
  t.my_key = u.my_key

Memfilter data untuk data yang condong

Praktik terbaik: Jika kueri Anda memproses kunci yang sangat condong ke beberapa nilai, filter data Anda sedini mungkin.

Kemiringan partisi, terkadang disebut kecondongan data, adalah saat data dipartisi menjadi partisi yang berukuran sangat tidak sama. Hal ini menciptakan ketidakseimbangan dalam jumlah data yang dikirim antar slot. Anda tidak dapat berbagi partisi antar-slot, jadi jika satu partisi sangat besar, partisi tersebut dapat memperlambat, atau bahkan menimbulkan error pada slot yang memproses partisi yang berukuran terlalu besar.

Partisi akan menjadi besar jika kunci partisi Anda memiliki nilai yang lebih sering muncul daripada nilai lainnya. Misalnya, mengelompokkan berdasarkan kolom user_id yang memiliki banyak entri untuk guest atau NULL.

Jika resource slot kewalahan, error resources exceeded akan muncul. Mencapai batas acak untuk slot (2 TB dalam memori yang dikompresi) juga menyebabkan shuffle menulis ke disk dan berdampak lebih lanjut pada performa. Pelanggan dengan harga berbasis kapasitas dapat meningkatkan jumlah slot yang dialokasikan.

Jika Anda memeriksa grafik eksekusi kueri dan melihat perbedaan signifikan antara waktu komputasi rata-rata dan maksimum, data Anda mungkin tidak akurat.

Untuk menghindari masalah performa yang disebabkan oleh kecondongan data:

  • Gunakan fungsi agregat perkiraan seperti APPROX_TOP_COUNT untuk menentukan apakah datanya condong.
  • Filter data Anda sedini mungkin.

Join yang tidak seimbang

Kemiringan data juga dapat muncul saat Anda menggunakan klausa JOIN. Karena BigQuery melakukan shuffle data di setiap sisi join, semua data dengan kunci gabungan yang sama akan menuju ke shard yang sama. Shuffling ini dapat membebani slot.

Untuk menghindari masalah performa yang terkait dengan join yang tidak seimbang, Anda dapat melakukan tugas-tugas berikut:

  • Filter baris dari tabel dengan kunci yang tidak seimbang.
  • Jika memungkinkan, bagi kueri menjadi dua kueri.
  • Gunakan pernyataan SELECT DISTINCT saat menentukan subkueri dalam klausa WHERE, untuk mengevaluasi nilai kolom yang unik saja satu kali.

    Misalnya, daripada gunakan klausa berikut yang berisi pernyataan SELECT:

    table1.my_id NOT IN (
      SELECT my_id
      FROM table2
      )
    

    Sebagai gantinya, gunakan klausa yang berisi pernyataan SELECT DISTINCT:

    table1.my_id NOT IN (
      SELECT DISTINCT my_id
      FROM table2
      )
    

Menggunakan nama alias untuk kolom yang bernama mirip

Praktik Terbaik: Gunakan alias kolom dan tabel saat Anda menggunakan kolom dengan nama serupa di seluruh kueri, termasuk subkueri.

Alias membantu mengidentifikasi kolom dan tabel mana yang direferensikan selain referensi awal kolom Anda. Menggunakan nama alias dapat membantu Anda memahami dan mengatasi masalah dalam kueri SQL, termasuk menemukan kolom yang digunakan dalam subkueri.

Menentukan batasan dalam skema tabel

Jika data tabel berisi batasan, tentukan batasan di skema tabel. Mesin kueri dapat mengoptimalkan rencana kueri menggunakan batasan tabel.

Menentukan batasan kunci utama dan kunci asing

Anda harus menentukan batasan kunci dalam skema tabel jika data tabel memenuhi persyaratan integritas data batasan kunci utama atau kunci asing. Mesin kueri dapat menggunakan batasan utama untuk mengoptimalkan paket kueri. Anda dapat menemukan informasi mendetail di postingan blog Bergabung dalam pengoptimalan dengan kunci utama dan kunci asing BigQuery.

BigQuery tidak memeriksa integritas data secara otomatis, jadi Anda harus memastikan bahwa data Anda memenuhi batasan yang ditentukan dalam skema tabel. Jika Anda tidak mempertahankan integritas data dalam tabel dengan batasan yang ditetapkan, hasil kueri Anda mungkin tidak akurat.

Langkah selanjutnya