Memecahkan masalah regresi performa

Saat Anda menggunakan kueri SQL untuk mencari data, Spanner akan otomatis menggunakan indeks sekunder yang cenderung membantu mengambil data secara lebih efisien. Namun, dalam beberapa kasus, Spanner mungkin memilih indeks yang menyebabkan kueri menjadi lebih lambat. Akibatnya, Anda mungkin melihat bahwa beberapa kueri berjalan lebih lambat daripada sebelumnya.

Halaman ini menjelaskan cara mendeteksi perubahan pada kecepatan eksekusi kueri; memeriksa rencana eksekusi kueri untuk kueri tersebut; dan menentukan indeks yang berbeda untuk kueri mendatang jika diperlukan.

Mendeteksi perubahan kecepatan eksekusi kueri

Anda kemungkinan besar akan melihat perubahan pada kecepatan eksekusi kueri setelah melakukan salah satu perubahan berikut:

  • Mengubah secara signifikan sejumlah besar data yang ada yang memiliki indeks sekunder.
  • Menambahkan, mengubah, atau menghapus indeks sekunder.

Anda dapat menggunakan beberapa alat untuk mengidentifikasi kueri tertentu yang dijalankan Spanner lebih lambat dari biasanya:

  • Insight kueri dan Statistik kueri.
  • Metrik latensi.

  • Metrik khusus aplikasi yang Anda rekam dan analisis dengan Cloud Monitoring. Misalnya, Anda dapat memantau metrik Jumlah kueri untuk menentukan jumlah kueri dalam instance dari waktu ke waktu dan untuk mengetahui versi pengoptimal kueri yang digunakan untuk menjalankan kueri.

  • Alat pemantauan sisi klien yang mengukur performa aplikasi Anda.

Catatan tentang database baru

Saat membuat kueri database yang baru dibuat dengan data yang baru disisipkan atau diimpor, Spanner mungkin tidak memilih indeks yang paling sesuai, karena pengoptimal kueri memerlukan waktu hingga tiga hari untuk mengumpulkan statistik pengoptimal secara otomatis. Untuk mengoptimalkan penggunaan indeks database Spanner baru lebih awal dari itu, Anda dapat membuat paket statistik baru secara manual.

Meninjau skema

Setelah Anda menemukan kueri yang melambat, lihat pernyataan SQL untuk kueri tersebut, dan identifikasi tabel yang digunakan pernyataan dan kolom yang diambilnya dari tabel tersebut.

Selanjutnya, temukan indeks sekunder yang ada untuk tabel tersebut. Tentukan apakah ada indeks yang menyertakan kolom yang Anda kueri, yang berarti Spanner mungkin menggunakan salah satu indeks untuk memproses kueri.

  • Jika ada indeks yang berlaku, langkah berikutnya adalah menemukan indeks yang digunakan Spanner untuk kueri.
  • Jika tidak ada indeks yang berlaku, gunakan perintah gcloud spanner operations list untuk memeriksa apakah Anda baru-baru ini menghapus indeks yang berlaku:

    gcloud spanner operations list \
        --instance=INSTANCE \
        --database=DATABASE \
        --filter="@TYPE:UpdateDatabaseDdlMetadata"
    

    Jika Anda menghapus indeks yang berlaku, perubahan tersebut mungkin telah memengaruhi performa kueri. Tambahkan kembali indeks sekunder ke tabel. Setelah Spanner menambahkan indeks, jalankan lagi kueri dan lihat performanya. Jika performa tidak meningkat, langkah berikutnya adalah menemukan indeks yang digunakan Spanner untuk kueri.

    Jika Anda tidak menghapus indeks yang berlaku, pemilihan indeks tidak menyebabkan performa kueri mengalami regresi. Cari perubahan lain pada data atau pola penggunaan Anda yang mungkin memengaruhi performa.

Menemukan indeks yang digunakan untuk kueri

Untuk mengetahui indeks yang digunakan Spanner untuk memproses kueri, lihat rencana eksekusi kueri di konsol Google Cloud:

  1. Buka halaman Instance Spanner di konsol Google Cloud.

    Buka halaman Instances

  2. Klik nama instance yang ingin Anda buat kueri.

  3. Di panel kiri, klik database yang ingin Anda buat kuerinya, lalu klik Spanner Studio.

  4. Masukkan kueri yang akan diuji.

  5. Di menu drop-down Run query, pilih Explanation only. Spanner menampilkan rencana kueri.

Cari setidaknya salah satu operator berikut dalam rencana kueri:

  • Pemindaian tabel
  • Pemindaian indeks
  • Cross apply atau distributed cross apply

Bagian berikut menjelaskan arti setiap operator.

Operator pemindaian tabel

Operator pemindaian tabel menunjukkan bahwa Spanner tidak menggunakan indeks sekunder:

Screenshot menampilkan operator pemindaian tabel dalam rencana kueri.

Misalnya, tabel Albums tidak memiliki indeks sekunder, dan Anda menjalankan kueri berikut:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

Karena tidak ada indeks yang dapat digunakan, rencana kueri menyertakan operator pemindaian tabel.

Operator pemindaian indeks

Operator pemindaian indeks menunjukkan bahwa Spanner menggunakan indeks sekunder saat memproses kueri:

Screenshot menampilkan operator pemindaian indeks dalam rencana kueri.

Misalnya, Anda menambahkan indeks ke tabel Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Kemudian, Anda menjalankan kueri berikut:

SELECT AlbumTitle FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

Indeks AlbumsByAlbumTitle berisi AlbumTitle, yang merupakan satu-satunya kolom yang dipilih kueri. Akibatnya, rencana kueri menyertakan operator pemindaian indeks.

Operator penerapan silang

Dalam beberapa kasus, Spanner menggunakan indeks yang hanya berisi beberapa kolom yang dipilih kueri. Akibatnya, Spanner harus menggabungkan indeks dengan tabel dasar.

Saat jenis join ini terjadi, rencana kueri akan menyertakan operator cross apply atau distributed cross apply yang memiliki input berikut:

  • Operator pemindaian indeks untuk indeks tabel
  • Operator pemindaian tabel untuk tabel yang memiliki indeks

Screenshot menampilkan cross apply terdistribusi dalam rencana kueri, dengan pemindaian indeks dan pemindaian tabel sebagai input.

Misalnya, Anda menambahkan indeks ke tabel Albums:

CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);

Kemudian, Anda menjalankan kueri berikut:

SELECT * FROM Albums WHERE STARTS_WITH(AlbumTitle, "Now");

Indeks AlbumsByAlbumTitle berisi AlbumTitle, tetapi kueri memilih semua kolom dalam tabel, bukan hanya AlbumTitle. Akibatnya, rencana kueri menyertakan operator cross apply terdistribusi, dengan pemindaian indeks AlbumsByAlbumTitle dan pemindaian tabel Albums sebagai inputnya.

Pilih indeks lain

Setelah Anda menemukan indeks yang digunakan Spanner untuk kueri, coba jalankan kueri dengan indeks yang berbeda, atau dengan memindai tabel dasar, bukan menggunakan indeks. Untuk menentukan indeks, tambahkan perintah FORCE_INDEX ke kueri.

Jika Anda menemukan versi kueri yang lebih cepat, update aplikasi Anda untuk menggunakan versi yang lebih cepat.

Panduan untuk memilih indeks

Gunakan panduan ini untuk menentukan indeks yang akan diuji untuk kueri:

  • Jika kueri Anda memenuhi salah satu kriteria berikut, coba gunakan tabel dasar, bukan indeks sekunder:

    • Kueri memeriksa kesetaraan dengan awalan kunci utama tabel dasar (misalnya, SELECT * FROM Albums WHERE SingerId = 1).
    • Sejumlah besar baris memenuhi predikat kueri (misalnya, SELECT * FROM Albums WHERE AlbumTitle != "There Is No Album With This Title").
    • Kueri menggunakan tabel dasar yang hanya berisi beberapa ratus baris.
  • Jika kueri berisi predikat yang sangat selektif (misalnya, REGEXP_CONTAINS, STARTS_WITH, <, <=, >, >=, atau !=), coba gunakan indeks yang menyertakan kolom yang sama dengan yang Anda gunakan dalam predikat.

Menguji kueri yang diperbarui

Gunakan konsol Google Cloud untuk menguji kueri yang diperbarui dan mengetahui waktu yang diperlukan untuk memproses kueri.

Jika kueri Anda menyertakan parameter kueri, dan parameter kueri terikat dengan beberapa nilai lebih sering daripada yang lain, maka ikat parameter kueri dengan salah satu nilai tersebut dalam pengujian Anda. Misalnya, jika kueri menyertakan predikat seperti WHERE country = @countryId, dan hampir semua kueri Anda mengikat @countryId ke nilai US, maka ikat @countryId ke US untuk pengujian performa Anda. Pendekatan ini membantu Anda mengoptimalkan kueri yang paling sering Anda jalankan.

Untuk menguji kueri yang diperbarui di konsol Google Cloud, ikuti langkah-langkah berikut:

  1. Buka halaman Instance Spanner di konsol Google Cloud.

    Buka halaman Instances

  2. Klik nama instance yang ingin Anda buat kueri.

  3. Di panel kiri, klik database yang ingin Anda buat kuerinya, lalu klik Spanner Studio.

  4. Masukkan kueri yang akan diuji, termasuk perintah FORCE_INDEX, lalu klik Run query.

    Konsol Google Cloud akan membuka tab Tabel hasil, lalu menampilkan hasil kueri, termasuk waktu yang diperlukan layanan Spanner untuk memproses kueri.

    Metrik ini tidak menyertakan sumber latensi lainnya, seperti waktu yang diperlukan Konsol Google Cloud untuk menafsirkan dan menampilkan hasil kueri.

Mendapatkan profil mendetail kueri dalam format JSON menggunakan REST API

Secara default, hanya hasil pernyataan yang ditampilkan saat Anda menjalankan kueri. Hal ini karena QueryMode disetel ke NORMAL. Untuk menyertakan statistik eksekusi mendetail dengan hasil kueri, tetapkan QueryMode ke PROFILE.

Membuat sesi

Sebelum memperbarui mode kueri, buat sesi, yang mewakili saluran komunikasi dengan layanan database Spanner.

  1. Klik projects.instances.databases.sessions.create.
  2. Berikan ID project, instance, dan database dalam formulir berikut:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]
    
  3. Klik Jalankan. Respons menunjukkan sesi yang Anda buat dalam formulir ini:

    projects/[\PROJECT_ID\]/instances/[\INSTANCE_ID\]/databases/[\DATABASE_ID\]/sessions/[\SESSION\]
    

    Anda akan menggunakannya untuk menjalankan profil kueri di langkah berikutnya. Sesi yang dibuat akan aktif selama maksimal satu jam di antara penggunaan berturut-turut sebelum dihapus oleh database.

Membuat profil kueri

Aktifkan mode PROFILE untuk kueri.

  1. Klik projects.instances.databases.sessions.executeSql.
  2. Untuk session, masukkan ID sesi yang Anda buat di langkah sebelumnya:

    projects/[PROJECT_ID]/instances/[INSTANCE_ID]/databases/[DATABASE_ID]/sessions/[SESSION]
    
  3. Untuk Isi permintaan, gunakan kode berikut:

    {
      "sql": "[YOUR_SQL_QUERY]",
      "queryMode": "PROFILE"
    }
    
  4. Klik Jalankan. Respons yang ditampilkan akan menyertakan hasil kueri, paket kueri, dan statistik eksekusi untuk kueri.