Linimasa dan paket kueri

Tersemat dalam tugas kueri, BigQuery menyertakan informasi paket kueri dan waktu diagnostik. Hal ini mirip dengan informasi yang diberikan oleh pernyataan seperti EXPLAIN dalam sistem analisis dan database lain. Informasi ini dapat diambil dari respons API metode seperti jobs.get.

Untuk kueri yang berjalan lama, BigQuery akan memperbarui statistik ini secara berkala. Pembaruan ini terjadi secara terpisah dari tingkat polling status tugas, tetapi biasanya tidak akan terjadi lebih sering dari setiap 30 detik. Selain itu, tugas kueri yang tidak menggunakan resource eksekusi, seperti permintaan uji coba atau hasil yang dapat disajikan dari hasil yang di-cache, tidak akan menyertakan informasi diagnostik tambahan, meskipun statistik lainnya mungkin ada.

Latar belakang

Saat menjalankan tugas kueri, BigQuery mengonversi pernyataan SQL deklaratif menjadi grafik eksekusi, yang dipecah menjadi serangkaian stage kueri, yang terdiri dari kumpulan yang lebih terperinci langkah-langkah eksekusi. BigQuery memanfaatkan arsitektur paralel yang sangat terdistribusi untuk menjalankan kueri ini. Stage akan membuat model unit tugas yang dapat dijalankan oleh banyak worker potensial secara paralel. Tahapan berkomunikasi satu sama lain menggunakan arsitektur shuffle terdistribusi cepat.

Dalam paket kueri, istilah unit tugas dan worker digunakan untuk menyampaikan informasi secara khusus tentang paralelisme. Di bagian lain dalam BigQuery, Anda mungkin menemukan istilah slot, yaitu representasi abstrak dari beberapa faset eksekusi kueri, termasuk komputasi, memori, dan resource I/O. Statistik tugas tingkat teratas memberikan perkiraan biaya kueri tertentu menggunakan estimasi totalSlotMs kueri menggunakan penghitungan terpisah ini.

Properti penting lainnya dari arsitektur eksekusi kueri adalah bersifat dinamis. Artinya, paket kueri dapat diubah saat kueri sedang berjalan. Stage yang diperkenalkan saat kueri berjalan sering digunakan untuk meningkatkan distribusi data di seluruh worker kueri. Dalam paket kueri di mana proses tersebut berlangsung, stage ini biasanya dilabeli sebagai Stage partisi ulang.

Selain paket kueri, tugas kueri juga mengekspos linimasa eksekusi, yang menyediakan akuntansi unit tugas yang telah selesai, tertunda, dan aktif dalam worker kueri. Kueri dapat memiliki beberapa tahap dengan pekerja aktif secara bersamaan, dan linimasa dimaksudkan untuk menunjukkan keseluruhan progres kueri.

Melihat informasi dengan Konsol Google Cloud

Di Konsol Google Cloud, Anda dapat melihat detail rencana kueri untuk kueri yang telah selesai dengan mengklik tombol Execution Details (di dekat tombol Results).

Paket kueri.

Informasi paket kueri

Dalam respons API, paket kueri direpresentasikan sebagai daftar stage kueri. Setiap item dalam daftar menunjukkan statistik ringkasan per stage, informasi langkah yang mendetail, dan klasifikasi pengaturan waktu stage. Tidak semua detail dirender dalam Konsol Google Cloud, tetapi semuanya dapat ada dalam respons API.

Ringkasan stage

Kolom ringkasan untuk setiap stage dapat mencakup hal berikut:

Kolom API Deskripsi
id ID numerik unik untuk stage.
name Nama ringkasan sederhana untuk stage. steps dalam stage memberikan detail tambahan tentang langkah-langkah eksekusi.
status Status eksekusi stage. Status yang mungkin termasuk PENDING, RUNNING, COMPLETE, FAILED, dan CANCELLED.
inputStages Daftar ID yang membentuk grafik dependensi stage. Misalnya, stage JOIN sering memerlukan dua stage dependen yang menyiapkan data di sisi kiri dan kanan hubungan JOIN.
startMs Stempel waktu, dalam epoch milidetik, yang merepresentasikan kapan worker pertama dalam stage memulai eksekusi.
endMs Stempel waktu, dalam epoch milidetik, yang merepresentasikan kapan worker terakhir menyelesaikan eksekusi.
steps Daftar langkah-langkah eksekusi yang lebih mendetail dalam stage. Lihat bagian berikutnya untuk mengetahui informasi selengkapnya.
recordsRead Ukuran input stage sebagai jumlah catatan, di semua worker stage.
recordsWritten Ukuran output stage sebagai jumlah catatan, di semua worker stage.
parallelInputs Jumlah unit tugas yang dapat diparalelkan untuk stage. Bergantung pada stage dan kueri, jumlah ini dapat mewakili jumlah segmen kolom dalam tabel, atau jumlah partisi dalam shuffle perantara.
completedParallelInputs Jumlah unit tugas dalam stage yang telah diselesaikan. Untuk sebagian kueri, tidak semua input dalam satu stage harus diselesaikan agar stage tersebut dapat diselesaikan.
shuffleOutputBytes Merepresentasikan total byte yang ditulis di semua worker dalam stage kueri.
shuffleOutputBytesSpilled Kueri yang mengirimkan data signifikan antar-stage mungkin perlu kembali ke transmisi berbasis disk. Statistik byte yang dialihkan menunjukkan berapa banyak data yang dialihkan ke disk. Bergantung pada algoritma pengoptimalan sehingga tidak bersifat deterministik untuk kueri tertentu.

Informasi langkah per stage

Langkah-langkah mewakili operasi yang lebih terperinci yang harus dijalankan oleh setiap worker dalam satu stage, yang ditampilkan sebagai daftar operasi yang diurutkan. Langkah-langkah akan dikategorikan, dengan beberapa operasi yang memberikan informasi yang lebih mendetail. Kategori operasi yang ada dalam paket kueri mencakup hal berikut:

Langkah Deskripsi
READ Pembacaan satu atau beberapa kolom dari tabel input atau shuffle tingkat menengah. Hanya enam belas kolom pertama yang dibaca yang ditampilkan dalam detail-detail langkah.
WRITE Penulisan satu atau beberapa kolom ke tabel output atau hasil menengah. Untuk output yang dipartisi HASH dari suatu stage, ini juga mencakup kolom yang digunakan sebagai kunci partisi.
COMPUTE Operasi seperti evaluasi ekspresi dan fungsi SQL.
FILTER Operator yang menerapkan klausa WHERE, OMIT IF, dan HAVING.
SORT Operasi Sort atau Order-By, mencakup kunci kolom dan arah pengurutan.
AGGREGATE Operasi agregasi, seperti GROUP BY atau COUNT.
LIMIT Operator yang menerapkan klausa LIMIT.
JOIN Operasi JOIN, yang mencakup tipe gabung dan kolom yang digunakan.
ANALYTIC_FUNCTION Pemanggilan fungsi jendela (juga dikenal sebagai "fungsi analisis").
USER_DEFINED_FUNCTION Panggilan ke fungsi yang ditentukan pengguna (UDF).

Klasifikasi pengaturan waktu per stage

Tahap kueri juga menyediakan klasifikasi waktu tahap, baik dalam bentuk relatif maupun absolut. Karena setiap tahap eksekusi mewakili pekerjaan yang dilakukan oleh satu atau beberapa pekerja independen, informasi diberikan dalam waktu rata-rata dan kasus terburuk. Waktu ini mewakili performa rata-rata untuk semua pekerja dalam suatu tahap serta performa pekerja paling lambat longtail untuk klasifikasi tertentu. Waktu rata-rata dan waktu maksimum selanjutnya di pilah menjadi representasi absolut dan relatif. Untuk statistik berbasis rasio, data disediakan sebagai pecahan dari waktu terlama yang dihabiskan oleh pekerja mana pun di segmen mana pun.

Konsol Google Cloud menyajikan pengaturan waktu stage menggunakan representasi pengaturan waktu relatif.

Informasi pengaturan waktu stage dilaporkan sebagai berikut:

Pengaturan waktu relatif Pengaturan waktu absolut Numerator rasio
waitRatioAvg waitMsAvg Waktu yang dihabiskan oleh worker rata-rata yang menunggu dijadwalkan.
waitRatioMax waitMsMax Waktu yang dihabiskan oleh worker paling lambat yang menunggu dijadwalkan.
readRatioAvg readMsAvg Waktu yang dihabiskan rata-rata worker untuk membaca data input.
readRatioMax readMsMax Waktu yang dihabiskan worker paling lambat untuk membaca data input.
computeRatioAvg computeMsAvg Waktu yang dihabiskan oleh rata-rata worker yang terikat ke CPU.
computeRatioMax computeMsMax Waktu yang dihabiskan oleh worker paling lambat yang terikat oleh CPU.
writeRatioAvg writeMsAvg Waktu yang dihabiskan oleh worker rata-rata untuk menulis data output.
writeRatioMax writeMsMax Waktu yang dihabiskan worker paling lambat untuk menulis data output.

Penjelasan untuk kueri gabungan

Kueri gabungan memungkinkan Anda mengirim pernyataan kueri ke sumber data eksternal menggunakan fungsi EXTERNAL_QUERY. Kueri gabungan tunduk pada teknik pengoptimalan yang dikenal sebagai bentang bawah SQL dan paket kueri akan menampilkan operasi yang didorong ke sumber data eksternal, jika ada. Misalnya, jika Anda menjalankan kueri berikut:

SELECT id, name
FROM EXTERNAL_QUERY("<connection>", "SELECT * FROM company")
WHERE country_code IN ('ee', 'hu') AND name like '%TV%'

Rencana kueri akan menampilkan langkah-langkah tahap berikut:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, country_code
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
  WHERE in(country_code, 'ee', 'hu')
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

Dalam paket ini, table_for_external_query_$_0(...) merepresentasikan fungsi EXTERNAL_QUERY. Dalam tanda kurung, Anda dapat melihat kueri yang dieksekusi sumber data eksternal. Berdasarkan hal itu, Anda dapat melihat bahwa:

  • Sumber data eksternal hanya menampilkan 3 kolom yang dipilih.
  • Sumber data eksternal hanya menampilkan baris yang country_code-nya adalah 'ee' atau 'hu'.
  • Operator LIKE tidak didorong ke bawah dan dievaluasi oleh BigQuery.

Sebagai perbandingan, jika tidak ada pushdown, rencana kueri akan menampilkan langkah-langkah tahap berikut:

$1:id, $2:name, $3:country_code
FROM table_for_external_query_$_0(
  SELECT id, name, description, country_code, primary_address, secondary address
  FROM (
    /*native_query*/
    SELECT * FROM company
  )
)
WHERE and(in($3, 'ee', 'hu'), like($2, '%TV%'))
$1, $2
TO __stage00_output

Kali ini sumber data eksternal menampilkan semua kolom serta semua baris dari tabel company dan BigQuery akan melakukan pemfilteran.

Metadata linimasa

Linimasa kueri melaporkan progres pada waktu tertentu, yang menyediakan tampilan snapshot progres kueri secara keseluruhan. Linimasa direpresentasikan sebagai serangkaian contoh yang melaporkan detail berikut:

Kolom Deskripsi
elapsedMs Milidetik berlalu sejak awal eksekusi kueri.
totalSlotMs Representasi kumulatif slot milidetik yang digunakan oleh kueri.
pendingUnits Total unit tugas yang dijadwalkan dan menunggu eksekusi.
activeUnits Total unit kerja aktif yang diproses oleh pekerja.
completedUnits Total unit tugas yang telah diselesaikan saat menjalankan kueri ini.

Contoh kueri

Kueri berikut menghitung jumlah baris dalam set data publik Shakespeare dan memiliki jumlah bersyarat kedua yang membatasi hasil pada baris yang merujuk ke 'hamlet':

SELECT
  COUNT(1) as rowcount,
  COUNTIF(corpus = 'hamlet') as rowcount_hamlet
FROM `publicdata.samples.shakespeare`

Klik Execution details untuk melihat paket kueri:

Paket kueri hamlet.

Indikator warna menunjukkan pengaturan waktu relatif untuk semua langkah di seluruh stage.

Untuk mempelajari lebih lanjut langkah-langkah stage eksekusi, klik untuk meluaskan detail stage tersebut:

Detail langkah paket kueri hamlet.

Dalam contoh ini, waktu terlama di segmen mana pun adalah waktu yang dihabiskan oleh satu worker di Stage 01 untuk menunggu Stage 00 selesai. Hal ini karena Tahap 01 bergantung pada input Tahap 00, dan tidak dapat dimulai sampai tahap pertama menulis outputnya ke dalam shuffle menengah.

Error Reporting

Tugas kueri mungkin saja gagal di tengah eksekusi. Karena informasi paket diperbarui secara berkala, Anda dapat mengamati di bagian mana kegagalan terjadi dalam grafik eksekusi. Dalam konsol Google Cloud, tahap yang berhasil atau gagal diberi label dengan tanda centang atau tanda seru di samping nama panggung.

Untuk mengetahui informasi lebih lanjut tentang cara menafsirkan dan mengatasi error, lihat panduan pemecahan masalah.

Representasi contoh API

Informasi paket kueri disematkan dalam informasi respons tugas, dan Anda dapat mengambilnya dengan memanggil jobs.get. Misalnya, kutipan respons JSON berikut untuk tugas yang menampilkan contoh kueri hamlet menunjukkan paket kueri dan informasi linimasa.

"statistics": {
  "creationTime": "1576544129234",
  "startTime": "1576544129348",
  "endTime": "1576544129681",
  "totalBytesProcessed": "2464625",
  "query": {
    "queryPlan": [
      {
        "name": "S00: Input",
        "id": "0",
        "startMs": "1576544129436",
        "endMs": "1576544129465",
        "waitRatioAvg": 0.04,
        "waitMsAvg": "1",
        "waitRatioMax": 0.04,
        "waitMsMax": "1",
        "readRatioAvg": 0.32,
        "readMsAvg": "8",
        "readRatioMax": 0.32,
        "readMsMax": "8",
        "computeRatioAvg": 1,
        "computeMsAvg": "25",
        "computeRatioMax": 1,
        "computeMsMax": "25",
        "writeRatioAvg": 0.08,
        "writeMsAvg": "2",
        "writeRatioMax": 0.08,
        "writeMsMax": "2",
        "shuffleOutputBytes": "18",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "164656",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$1:corpus",
              "FROM publicdata.samples.shakespeare"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$20 := COUNT($30)",
              "$21 := COUNTIF($31)"
            ]
          },
          {
            "kind": "COMPUTE",
            "substeps": [
              "$30 := 1",
              "$31 := equal($1, 'hamlet')"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$20, $21",
              "TO __stage00_output"
            ]
          }
        ]
      },
      {
        "name": "S01: Output",
        "id": "1",
        "startMs": "1576544129465",
        "endMs": "1576544129480",
        "inputStages": [
          "0"
        ],
        "waitRatioAvg": 0.44,
        "waitMsAvg": "11",
        "waitRatioMax": 0.44,
        "waitMsMax": "11",
        "readRatioAvg": 0,
        "readMsAvg": "0",
        "readRatioMax": 0,
        "readMsMax": "0",
        "computeRatioAvg": 0.2,
        "computeMsAvg": "5",
        "computeRatioMax": 0.2,
        "computeMsMax": "5",
        "writeRatioAvg": 0.16,
        "writeMsAvg": "4",
        "writeRatioMax": 0.16,
        "writeMsMax": "4",
        "shuffleOutputBytes": "17",
        "shuffleOutputBytesSpilled": "0",
        "recordsRead": "1",
        "recordsWritten": "1",
        "parallelInputs": "1",
        "completedParallelInputs": "1",
        "status": "COMPLETE",
        "steps": [
          {
            "kind": "READ",
            "substeps": [
              "$20, $21",
              "FROM __stage00_output"
            ]
          },
          {
            "kind": "AGGREGATE",
            "substeps": [
              "$10 := SUM_OF_COUNTS($20)",
              "$11 := SUM_OF_COUNTS($21)"
            ]
          },
          {
            "kind": "WRITE",
            "substeps": [
              "$10, $11",
              "TO __stage01_output"
            ]
          }
        ]
      }
    ],
    "estimatedBytesProcessed": "2464625",
    "timeline": [
      {
        "elapsedMs": "304",
        "totalSlotMs": "50",
        "pendingUnits": "0",
        "completedUnits": "2"
      }
    ],
    "totalPartitionsProcessed": "0",
    "totalBytesProcessed": "2464625",
    "totalBytesBilled": "10485760",
    "billingTier": 1,
    "totalSlotMs": "50",
    "cacheHit": false,
    "referencedTables": [
      {
        "projectId": "publicdata",
        "datasetId": "samples",
        "tableId": "shakespeare"
      }
    ],
    "statementType": "SELECT"
  },
  "totalSlotMs": "50"
},

Menggunakan informasi eksekusi

Paket kueri BigQuery memberikan informasi tentang cara layanan mengeksekusi kueri, tetapi sifat layanan yang terkelola membatasi bisa tidaknya beberapa detail ditindaklanjuti secara langsung. Banyak pengoptimalan terjadi secara otomatis menggunakan layanan ini, yang dapat berbeda dengan lingkungan lain karena penyesuaian, penyediaan, dan pemantauan dapat memerlukan staf khusus yang berpengetahuan luas.

Untuk mengetahui teknik tertentu yang dapat meningkatkan eksekusi dan performa kueri, baca dokumentasi praktik terbaik. Statistik paket dan linimasa kueri dapat membantu Anda memahami apakah stage tertentu mendominasi penggunaan resource. Misalnya, tahap JOIN yang menghasilkan baris output yang jauh lebih banyak daripada baris input dapat menunjukkan peluang untuk memfilter lebih awal dalam kueri.

Selain itu, informasi linimasa dapat membantu mengidentifikasi apakah kueri tertentu lambat secara terpisah atau karena efek dari kueri lain yang menangani resource yang sama. Jika Anda mengamati bahwa jumlah unit aktif tetap terbatas selama masa aktif kueri, tetapi jumlah unit tugas yang diantrekan tetap tinggi, hal ini dapat mewakili kasus ketika pengurangan jumlah kueri serentak dapat secara signifikan meningkatkan waktu eksekusi secara keseluruhan untuk kueri tertentu.