ضبط أداء الاستعلام باستخدام Azure Cosmos DB

ينطبق على: NoSQL

يوفر Azure Cosmos DB واجهة برمجة تطبيقات ل NoSQL للاستعلام عن البيانات، دون الحاجة إلى مخطط أو فهارس ثانوية. توفر هذه المقالة المعلومات التالية للمطورين:

  • تفاصيل عالية المستوى حول كيفية عمل تنفيذ استعلام SQL في Azure Cosmos DB
  • تلميحات وأفضل الممارسات لأداء الاستعلام
  • أمثلة على كيفية استخدام مقاييس تنفيذ استعلام SQL لتصحيح أداء الاستعلام

حول تنفيذ استعلام SQL

في Azure Cosmos DB يتم تخزين البيانات في حاويات، والتي يمكن أن تنمو إلى أي حجم تخزين أو معدل نقل الطلب. يقوم Azure Cosmos DB بتحجيم البيانات بسلاسة عبر الأقسام المادية تحت الأغطية للتعامل مع نمو البيانات أو الزيادات في معدل النقل المقدم. يمكنك إصدار استعلامات SQL لأي حاوية باستخدام واجهة برمجة تطبيقات REST أو أحد حزم SDK لـ SQL المدعومة.

نظرة عامة موجزة عن التقسيم: يمكنك تحديد مفتاح قسم مثل "city"، والذي يحدد كيفية تقسيم البيانات عبر الأقسام المادية. يتم تخزين البيانات التي تنتمي إلى مفتاح قسم واحد (على سبيل المثال، "المدينة" == "سياتل") داخل قسم فعلي، ويمكن لقسم فعلي واحد تخزين البيانات من مفاتيح أقسام متعددة. عندما يصل القسم إلى حد التخزين الخاص به، تقوم الخدمة بتقسيم القسم بسلاسة إلى قسمين جديدين. يتم توزيع البيانات بالتساوي عبر الأقسام الجديدة، مع الاحتفاظ بجميع البيانات لمفتاح قسم واحد معا. نظرا لأن الأقسام عابرة، تستخدم واجهات برمجة التطبيقات تجريدا لنطاق مفتاح القسم، والذي يشير إلى نطاقات تجزئة مفتاح القسم.

عند إصدار استعلام إلى Azure Cosmos DB، تقوم SDK بتنفيذ الخطوات المنطقية التالية:

  • تحليل استعلام SQL لتحديد خطة تنفيذ الاستعلام.
  • إذا كان الاستعلام يتضمن عامل تصفية مقابل مفتاح القسم، مثل SELECT * FROM c WHERE c.city = "Seattle"، يتم توجيهه إلى قسم واحد. إذا لم يكن الاستعلام يحتوي على عامل تصفية على مفتاح القسم، تنفيذه في جميع الأقسام ويتم دمج النتائج من كل قسم من جانب العميل.
  • يتم تنفيذ الاستعلام داخل كل قسم في سلسلة أو متوازية، بناءً على تكوين العميل. داخل كل قسم، قد يقوم الاستعلام برحلة واحدة أو أكثر ذهابًا وإيابًا بناءً على تعقيد الاستعلام وحجم الصفحة المكون والمعدل نقل المتوفرة للمجموعة. يقوم كل تنفيذ بإرجاع عدد وحدات الطلب التي يستهلكها تنفيذ الاستعلام وإحصائيات تنفيذ الاستعلام.
  • تُجري SDK تلخيصًا لنتائج الاستعلام عبر الأقسام. على سبيل المثال، إذا كان الاستعلام يتضمن ORDER BY عبر الأقسام، فسيتم فرز النتائج من الأقسام الفردية لإرجاع النتائج بترتيب عام. إذا كان الاستعلام تجميعًا مثل COUNT، فسيتم جمع الأعداد من الأقسام الفردية لإنتاج العدد الإجمالي.

توفر حزم SDK خيارات متنوعة لتنفيذ الاستعلام. على سبيل المثال، فيNET. تتوفر هذه الخيارات في فئة QueryRequestOptions . يصف الجدول التالي هذه الخيارات وكيفية تأثيرها على وقت تنفيذ الاستعلام.

خيار ‏‏الوصف
EnableScanInQuery قابل للتطبيق فقط إذا تم تعطيل الفهرسة لمسار المرشح المطلوب. يجب تعيين إلى true إذا قمت بإلغاء الاشتراك في الفهرسة وتريد تشغيل الاستعلامات باستخدام فحص كامل.
MaxItemCount الحد الأقصى لعدد العناصر التي يتم إرجاعها في كل رحلة ذهابًا وإيابًا إلى الخادم. يمكنك تعيينه إلى -1 للسماح للخادم بإدارة عدد العناصر التي سيتم إرجاعها.
MaxBufferedItemCount الحد الأقصى لعدد العناصر التي يمكن تخزينها مؤقتا من جانب العميل أثناء تنفيذ الاستعلام المتوازي. تحدد قيمة الخاصية الموجبة عدد العناصر المخزنة مؤقتا إلى قيمة المجموعة. يمكنك تعيينه إلى أقل من 0 للسماح للنظام تلقائيا بتحديد عدد العناصر المراد تخزينها مؤقتا.
MaxConcurrency يحصل على عدد العمليات المتزامنة التي تشغل جانب العميل أو يعينها أثناء تنفيذ الاستعلام المتوازي. تحدد قيمة الخاصية الموجبة عدد العمليات المتزامنة على القيمة المحددة. يمكنك تعيينه إلى أقل من 0 للسماح للنظام تلقائيا بتحديد عدد العمليات المتزامنة للتشغيل.
PopulateIndexMetrics تمكين مجموعة من مقاييس الفهرس لفهم كيفية استخدام محرك الاستعلام للفهارس الموجودة وكيفية استخدام الفهارس الجديدة المحتملة. يتحمل هذا الخيار حملا زائدا، لذلك يجب تمكينه فقط عند تصحيح أخطاء الاستعلامات البطيئة.
ResponseContinuationTokenLimitInKb يمكنك تحديد الحد الأقصى لحجم رمز المتابعة الذي يتم إرجاعه بواسطة الخادم. قد تحتاج إلى تعيين هذا إذا كان لمضيف التطبيق الخاص بك حدود على حجم عنوان الاستجابة، ولكن يمكن أن يزيد من المدة الإجمالية ووحدات الطلب المستهلكة للاستعلام.

على سبيل المثال، إليك استعلام على حاوية مقسمة /city باستخدام .NET SDK:

QueryDefinition query = new QueryDefinition("SELECT * FROM c WHERE c.city = 'Seattle'");
QueryRequestOptions options = new QueryRequestOptions()
{
    MaxItemCount = -1,
    MaxBufferedItemCount = -1,
    MaxConcurrency = -1,
    PopulateIndexMetrics = true
};
FeedIterator<dynamic> feedIterator = container.GetItemQueryIterator<dynamic>(query);

FeedResponse<dynamic> feedResponse = await feedIterator.ReadNextAsync();

يتوافق كل تنفيذ استعلام مع واجهة برمجة تطبيقات POST REST مع تعيين عناوين لخيارات طلب الاستعلام واستعلام SQL في النص الأساسي. للحصول على تفاصيل حول رؤوس وخيارات طلب REST API، راجع الاستعلام عن الموارد باستخدام REST API.

أفضل الممارسات لأداء الاستعلام

عادة ما يكون للعوامل التالية أكبر تأثير على أداء استعلام Azure Cosmos DB. نتعمق في كل من هذه العوامل في هذه المقالة.

العامل‬ تلميح
معدل النقل المتقدم قم بقياس RU لكل استعلام، وتأكد من أن لديك معدل النقل المطلوب المخصص لطلبات البحث الخاصة بك.
مفاتيح التقسيم والتقسيم قم بتفضيل الاستعلامات التي تحتوي على قيمة مفتاح القسم في بند عامل التصفية من أجل زمن انتقال منخفض.
SDK وخيارات الاستعلام اتبع أفضل ممارسات SDK مثل الاتصال المباشر وضبط خيارات تنفيذ الاستعلام من جانب العميل.
زمن الوصول إلى الشبكة قم بتشغيل التطبيق الخاص بك في نفس المنطقة مثل حساب Azure Cosmos DB حيثما أمكن لتقليل زمن الانتقال.
سياسة الفهرسة تأكد من أن لديك مسارات / نهج الفهرسة المطلوبة للاستعلام.
مقاييس تنفيذ الاستعلام قم بتحليل مقاييس تنفيذ الاستعلام لتحديد عمليات إعادة الكتابة المحتملة للاستعلام وأشكال البيانات.

معدل النقل المتقدم

في Azure Cosmos DB، يمكنك إنشاء حاويات من البيانات، كل منها مع التعبير عن معدل النقل المحجوز في وحدات الطلب (RU) في الثانية. قراءة مستند 1 كيلوبايت هي وحدة طلب واحدة، ويتم تسوية كل عملية (بما في ذلك الاستعلامات) إلى عدد ثابت من وحدات الطلب استنادا إلى تعقيدها. على سبيل المثال، إذا كان لديك 1000 وحدة طلب/ثانية تم توفيرها للحاوية الخاصة بك، وكان لديك استعلام مثل SELECT * FROM c WHERE c.city = 'Seattle' الذي يستهلك 5 وحدات طلب، فيمكنك تنفيذ (1000 RU/s) / (5 RU/query) = 200 من هذه الاستعلامات في الثانية.

إذا قمت بإرسال أكثر من 200 استعلام/ ثانية (أو بعض العمليات الأخرى التي تشبع جميع وحدات الطلب المقدمة)، تبدأ الخدمة في تحديد المعدل للطلبات الواردة. تتعامل SDKs تلقائيا مع تحديد المعدل عن طريق إجراء التراجع/إعادة المحاولة، لذلك قد تلاحظ زمن انتقال أعلى لهذه الاستعلامات. تعمل زيادة المعدل نقل المقدمة إلى القيمة المطلوبة على تحسين وقت استجابة الاستعلام وإنتاجيته.

لمعرفة المزيد حول وحدات الطلب، راجع طلب الوحدات.

مفاتيح التقسيم والتقسيم

باستخدام Azure Cosmos DB، يتم ترتيب السيناريوهات التالية لقراءة البيانات من الأسرع/الأكثر كفاءة عادة إلى الأبطأ/الأقل كفاءة.

  • GET على مفتاح قسم واحد ومعرف العنصر، والمعروف أيضا بقراءة النقطة
  • الاستعلام مع شرط عامل التصفية على مفتاح قسم واحد
  • الاستعلام باستخدام عبارة عامل تصفية المساواة أو النطاق على أي خاصية
  • استعلام بدون عوامل تصفية

الاستعلامات التي تحتاج إلى تنفيذ على جميع الأقسام لها زمن انتقال أعلى، ويمكن أن تستهلك وحدات طلب أعلى. نظرًا لأن كل قسم يحتوي على فهرسة تلقائية لجميع الخصائص، يمكن تقديم الاستعلام بكفاءة من الفهرس في هذه الحالة. يمكنك عمل استعلامات تمتد على الأقسام بشكل أسرع باستخدام خيارات التوازي.

لمعرفة المزيد حول مفاتيح التقسيم والتقسيم، راجع التقسيم في Azure Cosmos DB.

SDK وخيارات الاستعلام

راجع نصائح أداء الاستعلام واختبار الأداء لمعرفة كيفية الحصول على أفضل أداء من جانب العميل من Azure Cosmos DB باستخدام SDKs.

زمن الوصول إلى الشبكة

راجع التوزيع العالمي ل Azure Cosmos DB لمعرفة كيفية إعداد التوزيع العالمي والاتصال بأقرب منطقة. يكون لزمن انتقال الشبكة تأثير كبير على أداء الاستعلام عندما تحتاج إلى إجراء عدة رحلات ذهابا وابا أو استرداد مجموعة نتائج كبيرة من الاستعلام.

يمكنك استخدام مقاييس تنفيذ الاستعلام لاسترداد وقت تنفيذ الخادم للاستعلامات، ما يسمح لك بتمييز الوقت المستغرق في تنفيذ الاستعلام عن الوقت المستغرق في نقل الشبكة.

سياسة الفهرسة

راجع تكوين نهج الفهرسة للمسارات والأنواع والأوضاع الفهرسة وكيفية تأثيرها على تنفيذ الاستعلام. بشكل افتراضي، يطبق Azure Cosmos DB الفهرسة التلقائية على جميع البيانات ويستخدم فهارس النطاق للسلاسل والأرقام، وهو أمر فعال لاستعلامات المساواة. للحصول على سيناريوهات إدراج عالية الأداء، ضع في اعتبارك استبعاد المسارات لتقليل تكلفة وحدة الطلب لكل عملية إدراج.

يمكنك استخدام مقاييس الفهرس لتحديد الفهارس المستخدمة لكل استعلام وما إذا كانت هناك أي فهارس مفقودة من شأنها تحسين أداء الاستعلام.

مقاييس تنفيذ الاستعلام

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

تعرف على المزيد حول الحصول على مقاييس الاستعلام.

Metric الوحدة ‏‏الوصف
TotalTime مللي ثانية إجمالي وقت تنفيذ الاستعلام
DocumentLoadTime مللي ثانية الوقت المستغرق في تحميل المستندات
DocumentWriteTime مللي ثانية الوقت المستغرق في كتابة مستندات الإخراج وتسلسلها
IndexLookupTime مللي ثانية الوقت الذي يقضيه في طبقة الفهرس المادية
QueryPreparationTime مللي ثانية الوقت المستغرق في إعداد الاستعلام
RuntimeExecutionTime مللي ثانية إجمالي وقت تنفيذ وقت تشغيل الاستعلام
VMExecutionTime مللي ثانية الوقت المستغرق في وقت تشغيل الاستعلام في تنفيذ الاستعلام
OutputDocumentCount عدد عدد مستندات الإخراج في مجموعة النتائج
OutputDocumentSize عدد الحجم الإجمالي للمستندات الناتجة بالبايت
RetrievedDocumentCount عدد العدد الإجمالي للوثائق المسترجعة
RetrievedDocumentSize وحدات البايت الحجم الإجمالي للمستندات المستردة بالبايت
IndexHitRatio نسبة [0,1] نسبة عدد المستندات المطابقة بواسطة عامل التصفية إلى عدد المستندات التي تم تحميلها

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

فيما يلي بعض نماذج الاستعلامات، وكيفية تفسير بعض المقاييس التي يتم إرجاعها من تنفيذ الاستعلام:

الاستعلام مقياس العينة ‏‏الوصف
SELECT TOP 100 * FROM c "RetrievedDocumentCount": 101 عدد المستندات المسترجعة هو 100 + 1 لمطابقة بند TOP. يتم قضاء وقت الاستعلام في الغالب في WriteOutputTime وبما DocumentLoadTime أنه فحص.
SELECT TOP 500 * FROM c "RetrievedDocumentCount": 501 أصبح عدد المستندات المستردة أعلى الآن (500 + 1 لمطابقة بند TOP).
SELECT * FROM c WHERE c.N = 55 "IndexLookupTime": "00:00:00.0009500" يتم إنفاق حوالي 0.9 مللي ثانية في IndexLookupTime للبحث عن مفتاح، لأنه بحث في الفهرس على /N/?.
SELECT * FROM c WHERE c.N > 55 "IndexLookupTime": "00:00:00.0017700" مزيد من الوقت (1.7 مللي ثانية) الذي يقضيه في IndexLookupTime خلال فحص النطاق، لأنه بحث في الفهرس على /N/?.
SELECT TOP 500 c.N FROM c "IndexLookupTime": "00:00:00.0017700" نفس الوقت المنقضي على DocumentLoadTime مثل طلبات البحث السابقة، ولكن أقل DocumentWriteTime لأننا نتوقع فقط خاصية واحدة.
SELECT TOP 500 udf.toPercent(c.N) FROM c "RuntimeExecutionTime": "00:00:00.2136500" يتم إنفاق حوالي 213 مللي ثانية في RuntimeExecutionTime تنفيذ UDF على كل قيمة c.N.
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(c.Name, 'Den') "IndexLookupTime": "00:00:00.0006400", "RuntimeExecutionTime": "00:00:00.0074100" يتم إنفاق حوالي 0.6 مللي ثانية في IndexLookupTime يوم /Name/?. معظم وقت تنفيذ الاستعلام (حوالي 7 مللي ثانية) في RuntimeExecutionTime.
SELECT TOP 500 c.Name FROM c WHERE STARTSWITH(LOWER(c.Name), 'den') "IndexLookupTime": "00:00:00", "RetrievedDocumentCount": 2491, "OutputDocumentCount": 500 يتم تنفيذ الاستعلام على أنه مسح ضوئي لأنه يستخدم LOWER، ويتم إرجاع 500 مستند من أصل 2491 مستندًا تم استرداده.

الخطوات التالية