Optimalkan kueri dengan filter rentang dan ketidaksetaraan di beberapa kolom
Halaman ini memberikan contoh strategi pengindeksan yang harus digunakan untuk kueri dengan filter rentang & ketidaksetaraan di beberapa kolom untuk membuat pengalaman kueri yang efisien.
Baca konsep terkait sebelum mengoptimalkan kueri Anda.
Mengoptimalkan kueri dengan Penjelasan Kueri
Untuk menentukan apakah kueri dan indeks yang digunakan sudah optimal, Anda dapat menggunakan Query Explain untuk mendapatkan ringkasan paket kueri dan statistik eksekusi kueri:
Java
Query q = db.collection("employees").whereGreaterThan("salary",
100000).whereGreaterThan("experience", 0);
ExplainResults<QuerySnapshot> explainResults = q.explain(ExplainOptions.builder().analyze(true).build()).get();
ExplainMetrics metrics = explainResults.getMetrics();
PlanSummary planSummary = metrics.getPlanSummary();
ExecutionStats executionStats = metrics.getExecutionStats();
System.out.println(planSummary.getIndexesUsed());
System.out.println(stats.getResultsReturned());
System.out.println(stats.getExecutionDuration());
System.out.println(stats.getReadOperations());
System.out.println(stats.getDebugStats());
Node.js
let q = db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">",0);
let options = { analyze : 'true' };
let explainResults = await q.explain(options);
let planSummary = explainResults.metrics.planSummary;
let stats = explainResults.metrics.executionStats;
console.log(planSummary);
console.log(stats);
Contoh berikut menunjukkan bagaimana penggunaan pengurutan indeks yang benar dapat mengurangi jumlah entri indeks yang dipindai Firestore.
Kueri sederhana
Dengan contoh sebelumnya kumpulan karyawan, kueri sederhana
yang dijalankan dengan indeks (experience ASC, salary ASC)
adalah sebagai berikut:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Kueri memindai 95.000 entri indeks hanya untuk mengembalikan 5 dokumen. Karena predikat kueri tidak terpenuhi, sejumlah besar entri indeks dibaca, tetapi difilter.
// Output query planning info { "indexesUsed": [ { "properties": "(experience ASC, salary ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "2.5s", "readOperations": "100", "debugStats": { "index_entries_scanned": "95000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "95000", "small_ops": "0", "min_query_cost": "0" } } }
Kita dapat menyimpulkan dari keahlian domain bahwa sebagian besar karyawan akan memiliki setidaknya pengalaman, tetapi hanya sedikit yang akan memiliki gaji lebih dari 100.000. Dengan insight ini, kita dapat menyimpulkan bahwa batasan salary
lebih selektif daripada batasan experience
. Untuk memengaruhi indeks yang digunakan Firestore untuk menjalankan kueri, tentukan klausa orderBy
yang mengurutkan batasan salary
sebelum batasan experience
.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Jika Anda secara eksplisit menggunakan klausa orderBy()
untuk menambahkan predikat, Firestore akan menggunakan indeks (salary ASC, experience ASC)
untuk menjalankan kueri. Jadi, karena selektivitas filter rentang pertama lebih tinggi dalam kueri ini dibandingkan
kueri sebelumnya, kueri berjalan lebih cepat dan lebih hemat biaya.
// Output query planning info { "indexesUsed": [ { "properties": "(salary ASC, experience ASC, __name__ ASC)", "query_scope": "Collection" } ], // Output Query Execution Stats "resultsReturned": "5", "executionDuration": "0.2s", "readOperations": "6", "debugStats": { "index_entries_scanned": "1000", "documents_scanned": "5", "billing_details": { "documents_billable": "5", "index_entries_billable": "1000", "small_ops": "0", "min_query_cost": "0" } } }
Langkah Berikutnya
- Pelajari Query Explain.
- Pelajari praktik terbaik pengindeksan.