Trang này cung cấp các ví dụ về chiến lược lập chỉ mục mà bạn có thể sử dụng cho các truy vấn có bộ lọc phạm vi và bộ lọc bất đẳng thức trên nhiều trường để tạo trải nghiệm truy vấn hiệu quả.
Trước khi tối ưu hoá truy vấn, hãy đọc về các khái niệm liên quan.
Tối ưu hoá truy vấn bằng công cụ Giải thích truy vấn
Để xác định xem truy vấn và chỉ mục của bạn có tối ưu hay không, bạn có thể sử dụng Giải thích Truy vấn để xem bản tóm tắt kế hoạch truy vấn và số liệu thống kê về việc thực thi truy vấn:
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);
Ví dụ sau đây cho thấy cách sử dụng đúng thứ tự chỉ mục giúp giảm số lượng mục nhập chỉ mục mà Cloud Firestore quét.
Truy vấn đơn giản
Với ví dụ trước về một tập hợp nhân viên, truy vấn đơn giản
chạy với chỉ mục (experience ASC, salary ASC) như sau:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("experience")
.orderBy("salary");
Truy vấn chỉ quét 95.000 mục nhập chỉ mục để trả về 5 tài liệu. Vì vị từ truy vấn không được thoả mãn, nên một số lượng lớn mục nhập chỉ mục được đọc nhưng bị lọc.
// 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" } } }
Bạn có thể suy ra từ kiến thức chuyên môn về miền rằng hầu hết nhân viên sẽ có ít nhất một số kinh nghiệm nhưng ít người có mức lương cao hơn 100.000. Với thông tin chi tiết này, bạn có thể thấy rằng ràng buộc salary có tính chọn lọc cao hơn ràng buộc experience. Để ảnh hưởng đến chỉ mục mà Cloud Firestore sử dụng để thực thi truy vấn, hãy chỉ định một orderBy mệnh đề sắp xếp ràng buộc salary trước ràng buộc experience.
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Khi bạn sử dụng rõ ràng mệnh đề orderBy() để thêm vị từ,
Cloud Firestore sẽ sử dụng chỉ mục (salary ASC, experience ASC) để chạy truy vấn.
Vì tính chọn lọc của bộ lọc phạm vi đầu tiên cao hơn trong truy vấn này so với truy vấn trước đó, nên truy vấn chạy nhanh hơn và tiết kiệm chi phí hơn.
// 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" } } }