Mengoptimalkan performa BigQuery DataFrames

BigQuery DataFrames membantu Anda menganalisis dan mengubah data di BigQuery menggunakan API yang kompatibel dengan pandas. Untuk membuat pemrosesan data lebih cepat dan hemat biaya, Anda dapat menggunakan beberapa teknik untuk meningkatkan performa.

Dokumen ini menjelaskan cara berikut untuk mengoptimalkan performa:

Menggunakan mode pengurutan sebagian

BigQuery DataFrames memiliki fitur mode pengurutan, yang menerapkan urutan baris tertentu untuk operasi seperti fungsi jendela dan gabungan. Anda dapat menentukan mode pengurutan dengan menetapkan properti ordering_mode ke salah satu strict (dikenal sebagai mode pengurutan ketat, yang merupakan default) atau partial (dikenal sebagai mode pengurutan sebagian). Menggunakan setelan partial dapat membuat kueri Anda lebih efisien.

Mode pengurutan sebagian berbeda dengan mode pengurutan ketat. Mode pengurutan ketat mengatur semua baris dalam urutan tertentu. Pengurutan total ini membuat BigQuery DataFrames berfungsi lebih baik dengan pandas, sehingga Anda dapat mengakses baris berdasarkan urutannya menggunakan properti DataFrame.iloc. Namun, pengurutan total dan indeks berurutan defaultnya mencegah filter pada kolom atau baris mengurangi jumlah data yang dipindai. Pencegahan ini terjadi kecuali jika Anda menerapkan filter tersebut sebagai parameter ke fungsi read_gbq dan read_gbq_table. Untuk mengurutkan semua baris dalam DataFrame, BigQuery DataFrames membuat hash dari semua baris. Operasi ini dapat menyebabkan pemindaian data penuh yang mengabaikan filter baris dan kolom.

Mode pengurutan sebagian menghentikan BigQuery DataFrames membuat urutan total untuk semua baris dan menonaktifkan fitur yang memerlukan urutan total, seperti properti DataFrame.iloc. Mode pengurutan sebagian juga menetapkan DefaultIndexKindclass ke indeks null, bukan ke indeks berurutan.

Saat Anda memfilter objek DataFrame menggunakan mode pengurutan sebagian, BigQuery DataFrames tidak menghitung baris mana yang tidak ada dalam indeks berurutan. Mode pengurutan sebagian juga tidak otomatis menggabungkan data berdasarkan indeks. Pendekatan ini dapat meningkatkan efisiensi kueri Anda. Namun, baik Anda menggunakan mode pengurutan ketat default atau mode pengurutan sebagian, BigQuery DataFrames API berfungsi seperti pandas API yang sudah dikenal.

Dengan mode pengurutan sebagian dan ketat, Anda membayar resource BigQuery yang Anda gunakan. Namun, menggunakan mode pengurutan sebagian dapat menurunkan biaya saat menggunakan tabel berpartisi dan bercluster besar. Pengurangan biaya ini terjadi karena filter baris pada kolom cluster dan partisi mengurangi jumlah data yang diproses.

Mengaktifkan mode pengurutan sebagian

Untuk menggunakan pengurutan sebagian, tetapkan properti ordering_mode ke partial sebelum melakukan operasi lain dengan BigQuery DataFrames, seperti yang ditunjukkan dalam contoh kode berikut:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

Mode pengurutan sebagian mencegah gabungan implisit objek BigQuery DataFrames yang tidak terkait karena tidak memiliki indeks berurutan. Sebagai gantinya, Anda harus secara eksplisit memanggil metode DataFrame.merge untuk menggabungkan dua objek BigQuery DataFrames yang berasal dari ekspresi tabel yang berbeda.

Fitur Series.unique() dan Series.drop_duplicates() tidak berfungsi dengan mode pengurutan sebagian. Sebagai gantinya, gunakan metode groupby untuk menemukan nilai unik, seperti yang ditunjukkan dalam contoh berikut:

# Avoid order dependency by using groupby instead of drop_duplicates.
unique_col = df.groupby(["column"], as_index=False).size().drop(columns="size")

Dengan mode pengurutan sebagian, output fungsi DataFrame.head(n) dan Series.head(n) mungkin tidak sama setiap kali Anda menjalankannya. Untuk mendownload sampel data acak kecil, gunakan metode DataFrame.peek() atau Series.peek().

Untuk mengetahui tutorial mendetail yang menggunakan properti ordering_mode = "partial", lihat Menganalisis download paket dari PyPI dengan BigQuery DataFrames.

Pemecahan masalah

Karena BigQuery DataFrames dalam mode pengurutan sebagian terkadang tidak memiliki pengurutan atau indeks, Anda mungkin mengalami masalah berikut saat menggunakan beberapa metode yang kompatibel dengan pandas.

Error pengurutan diperlukan

Beberapa fitur, seperti fungsi DataFrame.head() dan DataFrame.iloc, memerlukan pengurutan. Untuk mengetahui daftar fitur yang memerlukan pengurutan, lihat kolom Memerlukan pengurutan di API pandas yang didukung.

Jika objek tidak memiliki pengurutan, operasi akan gagal dengan pesan OrderRequiredError seperti berikut: OrderRequiredError: Op iloc requires an ordering. Use .sort_values or .sort_index to provide an ordering.

Seperti yang dinyatakan dalam pesan error, Anda dapat memberikan pengurutan menggunakan metode DataFrame.sort_values() untuk mengurutkan berdasarkan satu atau beberapa kolom. Metode lain, seperti DataFrame.groupby(), secara implisit memberikan pengurutan total berdasarkan kunci pengelompokan.

Tidak seperti pandas, jika Anda berada dalam mode pengurutan sebagian, menjalankan kode yang sama dapat menghasilkan hasil yang berbeda setiap kali Anda menjalankannya. Untuk memastikan hasil yang konsisten, gunakan pengurutan total yang stabil untuk semua baris.

Error indeks null

Beberapa fitur, seperti properti DataFrame.unstack() dan Series.interpolate(), memerlukan indeks. Untuk mengetahui daftar fitur yang memerlukan indeks, lihat kolom Memerlukan indeks di API pandas yang didukung.

Saat Anda menggunakan operasi yang memerlukan indeks dengan mode pengurutan sebagian, operasi akan menampilkan pesan NullIndexError seperti berikut: NullIndexError: DataFrame cannot perform interpolate as it has no index. Set an index using set_index.

Seperti yang dinyatakan dalam pesan error, Anda dapat memberikan indeks menggunakan metode DataFrame.set_index()untuk mengurutkan berdasarkan satu atau beberapa kolom. Metode lain, seperti DataFrame.groupby(), secara implisit memberikan indeks berdasarkan kunci pengelompokan, kecuali jika parameter as_index=False ditetapkan.

Menyimpan hasil dalam cache setelah operasi yang mahal

BigQuery DataFrames menyimpan operasi secara lokal dan menunda menjalankan kueri hingga kondisi tertentu terpenuhi. Hal ini dapat menyebabkan operasi yang sama dijalankan beberapa kali di berbagai kueri.

Untuk menghindari pengulangan operasi yang mahal, simpan hasil perantara dengan metode cache(), seperti yang ditunjukkan dalam contoh berikut:

# Assume you have 3 large dataframes "users", "group" and "transactions"

# Expensive join operations
final_df = users.join(groups).join(transactions)
final_df.cache()
# Subsequent derived results will reuse the cached join
print(final_df.peek())
print(len(final_df[final_df["completed"]]))
print(final_df.groupby("group_id")["amount"].mean().peek(30))

Metode ini membuat tabel BigQuery sementara untuk menyimpan hasil Anda. Anda akan dikenai biaya untuk penyimpanan tabel sementara ini di BigQuery.

Melihat pratinjau data dengan metode peek()

BigQuery DataFrames menawarkan dua metode API untuk melihat pratinjau data:

  • peek(n) menampilkan n baris data, dengan n adalah jumlah baris.
  • head(n) menampilkan n baris data pertama, bergantung pada konteksnya, dengan n adalah jumlah baris.

Gunakan metode head() hanya jika urutan data penting, misalnya, saat Anda menginginkan lima nilai terbesar dalam kolom. Dalam kasus lain, gunakan metode peek() untuk pengambilan data yang lebih efisien, seperti yang ditunjukkan dalam contoh kode berikut:

import bigframes.pandas as bpd

# Read the "Penguins" table into a dataframe
df = bpd.read_gbq("bigquery-public-data.ml_datasets.penguins")

# Preview 3 random rows
df.peek(3)

Anda juga dapat menggunakan metode peek() untuk mendownload sampel data acak kecil saat menggunakan mode pengurutan sebagian.

Menunda pengambilan data repr()

Anda dapat memanggil metode repr() di BigQuery DataFrames dengan notebook atau debugger IDE. Panggilan ini memicu panggilan head() yang mengambil data sebenarnya. Pengambilan ini dapat memperlambat proses coding dan proses debug berulang Anda serta menimbulkan biaya.

Untuk mencegah metode repr() mengambil data, tetapkan atribut repr_mode ke "deferred", seperti yang ditunjukkan dalam contoh berikut:

import bigframes.pandas as bpd

bpd.options.display.repr_mode = "deferred"

Dalam mode tertunda, Anda hanya dapat melihat pratinjau data dengan panggilan eksplisit peek() dan head().

Langkah berikutnya