فهم أداء طلبات البحث باستخدام شرح طلب البحث

تتيح لك ميزة "تفسير طلب البحث" إرسال طلبات بحث Cloud Firestore إلى الخلفية والحصول على إحصاءات أداء مفصّلة حول تنفيذ طلبات البحث في الخلفية في المقابل. وتعمل هذه الدالة مثل عملية EXPLAIN [ANALYZE] في العديد من أنظمة قواعد البيانات الارتباطية.

يمكن إرسال طلبات Query Explain باستخدام مكتبات برامج خادم Firestore.

تساعدك نتائج Query Explain في فهم كيفية تنفيذ طلبات البحث، وتوضّح لك أوجه القصور ومواقع المشاكل المحتملة في جهة الخادم.

ميزة Query Explain:

  • يوفّر إحصاءات حول مرحلة تخطيط طلب البحث لتتمكّن من تعديل فهارس طلبات البحث وتعزيز الكفاءة.
  • يساعدك استخدام خيار التحليل في فهم التكلفة والأداء لكل طلب، ويتيح لك تكرار أنماط الطلبات المختلفة بسرعة من أجل تحسين استخدامها.

التعرّف على خيارات Query Explain: التلقائي والتحليل

يمكن تنفيذ عمليات Query Explain باستخدام الخيار التلقائي أو الخيار تحليل.

باستخدام الخيار التلقائي، تخطّط ميزة "تفسير طلب البحث" لطلب البحث، ولكنّها تتخطّى مرحلة التنفيذ. سيؤدي ذلك إلى عرض معلومات مرحلة المخطِّط. يمكنك استخدام هذه الميزة للتحقّق من أنّ طلب البحث يتضمّن الفهارس اللازمة ومعرفة الفهارس المستخدَمة. سيساعدك ذلك في التحقّق، على سبيل المثال، من أنّ طلب بحث معيّن يستخدم فهرسًا مركّبًا بدلاً من التقاطع مع العديد من الفهارس المختلفة.

باستخدام خيار التحليل، يخطّط Query Explain لطلب البحث وينفّذه. يؤدي هذا إلى عرض جميع معلومات المخطط المذكورة سابقًا إلى جانب إحصاءات من وقت تشغيل تنفيذ الاستعلام. سيشمل ذلك معلومات الفوترة الخاصة بطلب البحث بالإضافة إلى إحصاءات على مستوى النظام حول تنفيذ طلب البحث. يمكنك استخدام هذه الأداة لاختبار إعدادات مختلفة لطلبات البحث والفهرسة من أجل تحسين تكلفتها وسرعتها.

ما هي تكلفة ميزة "تفسير طلب البحث"؟

عند استخدام ميزة "توضيح طلب البحث" مع الخيار التلقائي، لا يتم تنفيذ أي عمليات فهرسة أو قراءة. بغض النظر عن مدى تعقيد طلب البحث، يتم تحصيل رسوم مقابل عملية قراءة واحدة.

عند استخدام ميزة "تفسير طلب البحث" مع خيار التحليل، يتم تنفيذ عمليات الفهرسة والقراءة، لذا يتم تحصيل رسوم منك مقابل طلب البحث كالمعتاد. لا توجد رسوم إضافية لنشاط التحليل، فقط الرسوم المعتادة للاستعلام الذي يتم تنفيذه.

استخدام ميزة "تفسير طلب البحث" مع الخيار التلقائي

يمكنك استخدام مكتبات العملاء لإرسال طلب خيار تلقائي.

يُرجى العِلم أنّه تتم مصادقة الطلبات باستخدام "إدارة الهوية وإمكانية الوصول"، وذلك من خلال استخدام الأذونات نفسها لعمليات طلبات البحث العادية. ويتم تجاهل أساليب المصادقة الأخرى، مثل Firebase Authentication. لمزيد من المعلومات، يُرجى الاطّلاع على الدليل حول إدارة الهوية وإمكانية الوصول لمكتبات برامج الخادم.

Java (مشرف)

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 (المشرف)

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)"},
    ]
}

لمزيد من المعلومات، يُرجى الاطّلاع على مرجع تقرير "تفسير طلب البحث".

استخدام ميزة "تفسير طلب البحث" مع خيار التحليل

يمكنك استخدام مكتبات العملاء لإرسال طلب خيار التحليل.

يُرجى العِلم أنّه تتم مصادقة الطلبات باستخدام "إدارة الهوية وإمكانية الوصول"، وذلك من خلال استخدام الأذونات نفسها لعمليات طلبات البحث العادية. ويتم تجاهل أساليب المصادقة الأخرى، مثل Firebase Authentication. لمزيد من المعلومات، يُرجى الاطّلاع على الدليل حول إدارة الهوية وإمكانية الوصول لمكتبات برامج الخادم.

Java (مشرف)

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 (المشرف)

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';

إذا استخدمنا خيار التحليل، ستعرض المقاييس التي تم عرضها أنّ طلب البحث يتم تنفيذه على فهرسَين بحقل واحد، هما (category ASC, __name__ ASC) و(country ASC, __name__ ASC). ويفحص 16500 إدخال في الفهرس، ولكنه يعرض 1200 مستند فقط.

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