ทำความเข้าใจประสิทธิภาพของการค้นหาโดยใช้คำอธิบายการค้นหา

Query Explain ช่วยให้คุณส่งCloud Firestoreคำค้นหาไปยังแบ็กเอนด์และรับสถิติประสิทธิภาพโดยละเอียดเกี่ยวกับการดำเนินการคำค้นหาแบ็กเอนด์เป็นการตอบแทน โดยจะทำงานเหมือนกับตัวดำเนินการ EXPLAIN [ANALYZE] ในระบบฐานข้อมูลเชิงสัมพันธ์หลายระบบ

คุณส่งคำขออธิบายการค้นหาได้โดยใช้ไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์ Firestore

ผลลัพธ์ของคำอธิบายการค้นหาจะช่วยให้คุณเข้าใจวิธีดำเนินการค้นหา โดยจะแสดงจุดที่ไม่มีประสิทธิภาพและตำแหน่งของคอขวดฝั่งเซิร์ฟเวอร์ที่อาจเกิดขึ้น

คำอธิบายการค้นหา:

  • ให้ข้อมูลเชิงลึกเกี่ยวกับระยะการวางแผนการค้นหาเพื่อให้คุณปรับดัชนีการค้นหาและเพิ่มประสิทธิภาพได้
  • การใช้ตัวเลือกวิเคราะห์จะช่วยให้คุณเข้าใจต้นทุนและประสิทธิภาพในระดับการค้นหาแต่ละรายการ และช่วยให้คุณวนซ้ำรูปแบบการค้นหาต่างๆ ได้อย่างรวดเร็วเพื่อเพิ่มประสิทธิภาพการใช้งาน

ทำความเข้าใจตัวเลือกการอธิบายการค้นหา: ค่าเริ่มต้นและการวิเคราะห์

คุณสามารถดำเนินการอธิบายการค้นหาได้โดยใช้ตัวเลือกค่าเริ่มต้นหรือตัวเลือกวิเคราะห์

ตัวเลือกเริ่มต้นจะทำให้ Query Explain วางแผนการค้นหา แต่ข้าม ขั้นตอนการดำเนินการ ซึ่งจะแสดงข้อมูลระยะวางแผน คุณสามารถ ใช้สิ่งนี้เพื่อตรวจสอบว่าการค้นหามีดัชนีที่จำเป็นและทำความเข้าใจว่ามีการใช้ดัชนีใด ซึ่งจะช่วยให้คุณตรวจสอบได้ เช่น ว่าคําค้นหาหนึ่งๆ ใช้ดัชนีแบบผสมแทนการตัดกันของดัชนีที่แตกต่างกันหลายรายการ

ตัวเลือกวิเคราะห์จะทำให้ Query Explain ทั้งวางแผนและดำเนินการ ค้นหา ซึ่งจะแสดงข้อมูลเครื่องมือวางแผนที่กล่าวถึงก่อนหน้านี้ทั้งหมดพร้อมกับ สถิติจากรันไทม์การดำเนินการคำค้นหา ซึ่งจะรวมถึงข้อมูลการเรียกเก็บเงินของคําค้นหาพร้อมข้อมูลเชิงลึกระดับระบบเกี่ยวกับการดําเนินการคําค้นหา คุณสามารถใช้เครื่องมือนี้เพื่อทดสอบการกำหนดค่าการค้นหาและดัชนีต่างๆ เพื่อเพิ่มประสิทธิภาพต้นทุนและเวลาในการตอบสนอง

Query Explain มีค่าใช้จ่ายเท่าใด

เมื่อใช้คำอธิบายการค้นหาด้วยตัวเลือกเริ่มต้น ระบบจะไม่ดำเนินการดัชนีหรือการอ่าน ไม่ว่าการค้นหาจะซับซ้อนเพียงใด ระบบจะเรียกเก็บเงินสำหรับการดำเนินการอ่าน 1 ครั้ง

เมื่อใช้ Query Explain กับตัวเลือกการวิเคราะห์ ระบบจะดำเนินการดัชนีและการอ่าน ดังนั้นคุณจะถูกเรียกเก็บเงินสำหรับการค้นหาตามปกติ ไม่มีค่าใช้จ่ายเพิ่มเติมสำหรับกิจกรรมการวิเคราะห์ มีเพียงค่าใช้จ่ายปกติสำหรับคําค้นหาที่ ดำเนินการ

ใช้คำอธิบายการค้นหาด้วยตัวเลือกเริ่มต้น

คุณใช้ไลบรารีของไคลเอ็นต์เพื่อส่งคำขอตัวเลือกเริ่มต้นได้

โปรดทราบว่าระบบจะตรวจสอบสิทธิ์คำขอด้วย IAM โดยใช้สิทธิ์เดียวกัน สำหรับการดำเนินการค้นหาปกติ ระบบจะไม่สนใจเทคนิคการตรวจสอบสิทธิ์อื่นๆ เช่น Firebase Authentication ดูข้อมูลเพิ่มเติมได้ที่คู่มือเกี่ยวกับ IAM สำหรับไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์


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();

    

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;

    

รูปแบบที่แน่นอนของการตอบกลับจะขึ้นอยู่กับสภาพแวดล้อมการดำเนินการ คุณแปลงผลลัพธ์ที่แสดงเป็น JSON ได้ เช่น

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

ดูข้อมูลเพิ่มเติมได้ที่ข้อมูลอ้างอิงรายงานคำอธิบายการค้นหา

ใช้ Query Explain กับตัวเลือกการวิเคราะห์

คุณใช้ไลบรารีของไคลเอ็นต์เพื่อส่งคำขอตัวเลือกวิเคราะห์ได้

โปรดทราบว่าระบบจะตรวจสอบสิทธิ์คำขอด้วย IAM โดยใช้สิทธิ์เดียวกัน สำหรับการดำเนินการค้นหาปกติ ระบบจะไม่สนใจเทคนิคการตรวจสอบสิทธิ์อื่นๆ เช่น Firebase Authentication ดูข้อมูลเพิ่มเติมได้ที่คู่มือเกี่ยวกับ IAM สำหรับไลบรารีของไคลเอ็นต์เซิร์ฟเวอร์


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();

    

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;

    

ตัวอย่างต่อไปนี้แสดงออบเจ็กต์ stats ที่แสดงผลนอกเหนือจาก planInfo รูปแบบที่แน่นอนของการตอบกลับจะขึ้นอยู่กับสภาพแวดล้อมการดำเนินการ การตอบกลับตัวอย่างอยู่ในรูปแบบ JSON

{
    "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",
               }
    }

}

ดูข้อมูลเพิ่มเติมได้ที่ข้อมูลอ้างอิงรายงานคำอธิบายการค้นหา

ตีความผลลัพธ์และทำการปรับเปลี่ยน

มาดูตัวอย่างสถานการณ์ที่เราค้นหาภาพยนตร์ตามประเภทและ ประเทศที่ผลิตกัน

สมมติว่ามีการค้นหา SQL ที่เทียบเท่านี้เพื่อเป็นตัวอย่าง

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

หากเราใช้ตัวเลือกวิเคราะห์ เมตริกที่แสดงจะแสดงการค้นหา ที่ทำงานในดัชนีฟิลด์เดียว 2 รายการ (category ASC, __name__ ASC) และ (country ASC, __name__ ASC) โดยจะสแกนรายการดัชนี 16,500 รายการ แต่แสดงเอกสารเพียง 1,200 รายการ

// 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",
               }
    }
}

คุณสามารถสร้างดัชนีแบบผสมที่ครอบคลุมทั้งหมด(category ASC, country ASC, __name__ ASC)เพื่อเพิ่มประสิทธิภาพการเรียกใช้คําค้นหา

การเรียกใช้การค้นหาด้วยตัวเลือกวิเคราะห์อีกครั้งจะแสดงให้เห็นว่าระบบเลือกดัชนีที่สร้างขึ้นใหม่สำหรับการค้นหานี้ และการค้นหาจะทำงานได้เร็วขึ้นและมีประสิทธิภาพมากขึ้น

// 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",
               }
    }
}