Memahami performa kueri menggunakan Penjelasan Kueri

Dengan Query Explain, Anda dapat mengirimkan kueri Firestore ke backend dan menerima statistik performa mendetail tentang eksekusi kueri backend sebagai gantinya. Library ini berfungsi seperti operasi EXPLAIN [ANALYZE] di banyak sistem database relasional.

Permintaan Query Explain dapat dikirim menggunakan library klien server Firestore.

Hasil Query Explain membantu Anda memahami bagaimana kueri dieksekusi, menunjukkan inefisiensi dan lokasi kemungkinan kemacetan sisi server.

Penjelasan Kueri:

  • Memberikan insight tentang fase perencanaan kueri, sehingga Anda dapat menyesuaikan indeks kueri dan meningkatkan efisiensi.
  • Dengan menggunakan opsi analisis, Anda dapat memahami biaya dan performa per kueri, serta memungkinkan Anda dengan cepat melakukan iterasi melalui berbagai pola kueri untuk mengoptimalkan penggunaannya.

Memahami opsi Penjelasan Kueri: default dan analisis

Operasi Query Explain dapat dilakukan menggunakan opsi default atau opsi analyze.

Dengan opsi default, Query Explain akan merencanakan kueri, tetapi akan melewati tahap eksekusi. Tindakan ini akan menampilkan informasi tahap perencana. Anda dapat menggunakannya untuk memeriksa apakah kueri memiliki indeks yang diperlukan dan memahami indeks mana yang digunakan. Hal ini akan membantu Anda memverifikasi, misalnya, bahwa kueri tertentu menggunakan indeks komposit daripada harus berpotongan dengan banyak indeks yang berbeda.

Dengan opsi analisis, Query Explain kedua paket dan menjalankan kueri. Tindakan ini akan menampilkan semua informasi perencana yang disebutkan sebelumnya beserta statistik dari runtime eksekusi kueri. Hal ini akan mencakup informasi penagihan kueri beserta insight tingkat sistem terkait eksekusi kueri. Anda dapat menggunakan alat ini untuk menguji berbagai konfigurasi indeks dan kueri guna mengoptimalkan biaya dan latensi.

Apa yang dimaksud dengan biaya Penjelasan Kueri?

Saat Anda menggunakan Query Explain dengan opsi default, tidak ada operasi indeks atau baca yang dilakukan. Terlepas dari kompleksitas kueri, satu operasi baca akan dikenai biaya.

Saat Anda menggunakan Query Explain dengan opsi analisis, operasi indeks dan baca akan dilakukan, sehingga Anda akan dikenai biaya untuk kueri seperti biasa. Tidak ada biaya tambahan untuk aktivitas analisis, hanya biaya biasa untuk kueri yang dijalankan.

Menggunakan Jelaskan Kueri dengan opsi default

Anda dapat menggunakan library klien untuk mengirimkan permintaan opsi default.

Perlu diperhatikan bahwa permintaan diautentikasi dengan IAM, menggunakan izin yang sama untuk operasi kueri reguler. Teknik autentikasi lainnya, seperti Firebase Authentication, akan diabaikan. Untuk informasi lebih lanjut, lihat panduan tentang IAM untuk library klien server.

Java (Admin)

Query q = db.collection("col").whereGreaterThan("a", 1);
ExplainOptions options = ExplainOptions.builder().build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();

    
Node (Admin)

const q = db.collection('col').where('country', '=', 'USA');
const options = { analyze : 'false' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;

    

Hasil yang ditampilkan dapat dikonversi ke JSON. Contoh:

{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

Untuk informasi selengkapnya, lihat referensi laporan Jelaskan Kueri.

Menggunakan Query Explain dengan opsi analisis

Anda dapat menggunakan library klien untuk mengirimkan permintaan opsi analisis.

Perlu diperhatikan bahwa permintaan diautentikasi dengan IAM, menggunakan izin yang sama untuk operasi kueri reguler. Teknik autentikasi lainnya, seperti Firebase Authentication, akan diabaikan. Untuk informasi lebih lanjut, lihat panduan tentang IAM untuk library klien server.

Java (Admin)

Query q = db.collection("col").whereGreaterThan("a", 1);

ExplainOptions options = ExplainOptions.builder().setAnalyze(true).build();

ExplainResults<QuerySnapshot> explainResults = q.explain(options).get();

ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
List<Map<String, Object>> indexesUsed = planSummary.getIndexesUsed();
ExecutionStats stats = metrics.getExecutionStats();

    
Node (Admin)

const q = db.collection('col').where('country', '=', 'USA');

const options = { analyze : 'true' };

const explainResults = await q.explain(options);

const metrics = explainResults.metrics;
const plan = metrics.planSummary;
const indexesUsed = plan.indexesUsed;
const stats = metrics.executionStats;

    

Hasil yang ditampilkan dapat dikonversi ke JSON. Contoh berikut menunjukkan objek stats yang sekarang akan kita dapatkan selain planInfo.

{
    "resultsReturned": "5",
    "executionDuration": "0.100718s",
    "readOperations": "5",
    "debugStats": {
               "index_entries_scanned": "95000",
               "documents_scanned": "5"
               "billing_details": {
                     "documents_billable": "5",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }

}

Untuk informasi selengkapnya, lihat referensi laporan Jelaskan Kueri.

Menafsirkan hasil dan melakukan penyesuaian

Mari kita lihat sebuah contoh skenario di mana kita membuat kueri film berdasarkan genre dan negara produksi.

Sebagai ilustrasi, asumsikan nilai yang setara dengan kueri SQL ini.

SELECT *
FROM /movies
WHERE category = 'Romantic' AND country = 'USA';

Jika kita menggunakan opsi analisis, metrik yang ditampilkan akan menunjukkan bahwa kueri berjalan pada dua indeks kolom tunggal, (category ASC, __name__ ASC) dan (country ASC, __name__ ASC). Metode ini memindai 16.500 entri indeks, tetapi hanya menampilkan 1.200 dokumen.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, __name__ ASC)"},
        {"query_scope": "Collection", "properties": "(country ASC, __name__ ASC)"},
    ]
}

// Output query status
{
    "resultsReturned": "1200",
    "executionDuration": "0.118882s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "16500",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}

Untuk mengoptimalkan performa eksekusi kueri, Anda dapat membuat (category ASC, country ASC, __name__ ASC) indeks komposit yang tercakup sepenuhnya.

Dengan menjalankan kembali kueri dengan opsi analisis, kita dapat melihat bahwa indeks yang baru dibuat dipilih untuk kueri ini, dan kueri tersebut berjalan jauh lebih cepat dan lebih efisien.

// Output query planning info
{
    "indexes_used": [
        {"query_scope": "Collection", "properties": "(category ASC, country ASC,  __name__ ASC)"}
    ]
}

// Output query stats
{
    "resultsReturned": "1200",
    "executionDuration": "0.026139s",
    "readOperations": "1200",
    "debugStats": {
               "index_entries_scanned": "1200",
               "documents_scanned": "1200"
               "billing_details": {
                     "documents_billable": "1200",
                     "index_entries_billable": "0",
                     "small_ops": "0",
                     "min_query_cost": "0",
               }
    }
}