مشاركة عبر


نصائح بخصوص أداء الاستعلام لـ Azure Cosmos DB SDKS

Azure Cosmos DB عبارة عن قاعدة بيانات سريعة ومرنة موزعة تتوسع بسلاسة مع مستويات إنتاجية وزمن وصول مضمونة. لا يتعين عليك إجراء تغييرات هيكلية كبيرة أو كتابة تعليمات برمجية معقدة لتوسيع نطاق قاعدة البيانات باستخدام Azure Cosmos DB. يُعد توسيع النطاق وتقليصه أمراً سهلاً مثل استدعاء واجهة برمجة التطبيقات للنظام. لمعرفة مزيد، راجع توفير معدل نقل الحاوية أو توفير معدل نقل قاعدة البيانات.

تقليل استدعاءات خطة الاستعلام

لتنفيذ استعلام، يجب إنشاء خطة استعلام. تضيف طلبات الشبكة إلى بوابة Azure Cosmos DB إلى زمن انتقال عملية الاستعلام. هناك طريقتان لإزالة هذا الطلب وتقليل زمن انتقال عملية الاستعلام:

تحسين استعلامات القسم الفردي باستخدام التنفيذ المباشر المتفائل

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

إشعار

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

يتوفر ODE الآن في الإصدار 3.38.0 من .NET SDK والإصدارات الأحدث. عند تنفيذ استعلام وتحديد مفتاح قسم في الطلب أو الاستعلام نفسه، أو عندما تحتوي قاعدة البيانات على قسم فعلي واحد فقط، يمكن لتنفيذ الاستعلام استخدام مزايا ODE. لتمكين ODE، قم بالتعيين EnableOptimisticDirectExecution إلى true في QueryRequestOptions.

يمكن أن تستفيد استعلامات القسم الفردي التي تتميز بدوال GROUP BYوORDER BYوDISTINCT والتجميع (مثل المجموع والمتوسط والحد الأدنى والحد الأقصى) بشكل كبير من استخدام ODE. ومع ذلك، في السيناريوهات التي يستهدف فيها الاستعلام أقساما متعددة أو لا يزال يتطلب ترقيم الصفحات، قد يكون زمن انتقال استجابة الاستعلام وتكلفة RU أعلى من استخدام ODE. لذلك ، عند استخدام ODE ، يجب عليك:

  • حدد مفتاح القسم في الاستدعاء أو الاستعلام نفسه.
  • تأكد من أن حجم البيانات لم ينمو وتسبب في تقسيم القسم.
  • تأكد من أن نتائج الاستعلام لا تتطلب ترقيم الصفحات للحصول على الفائدة الكاملة من ODE.

فيما يلي بعض الأمثلة على استعلامات القسم الفردي البسيطة التي يمكن أن تستفيد من ODE:

- SELECT * FROM r
- SELECT * FROM r WHERE r.pk == "value"
- SELECT * FROM r WHERE r.id > 5
- SELECT r.id FROM r JOIN id IN r.id
- SELECT TOP 5 r.id FROM r ORDER BY r.id
- SELECT * FROM r WHERE r.id > 5 OFFSET 5 LIMIT 3 

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

- SELECT Count(r.id) AS count_a FROM r
- SELECT DISTINCT r.id FROM r
- SELECT Max(r.a) as min_a FROM r
- SELECT Avg(r.a) as min_a FROM r
- SELECT Sum(r.a) as sum_a FROM r WHERE r.a > 0 

يمكن أن تتطلب بعض الاستعلامات المعقدة دائما التوزيع، حتى إذا كانت تستهدف قسما واحدا. ومن أمثلة هذه الاستعلامات ما يلي:

- SELECT Sum(id) as sum_id FROM r JOIN id IN r.id
- SELECT DISTINCT r.id FROM r GROUP BY r.id
- SELECT DISTINCT r.id, Sum(r.id) as sum_a FROM r GROUP BY r.id
- SELECT Count(1) FROM (SELECT DISTINCT r.id FROM root r)
- SELECT Avg(1) AS avg FROM root r 

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

إشعار

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

  • قم بالترقية إلى SDK الجديد وتعطيل ODE، وكلاهما معا كجزء من عملية نشر واحدة. انتظر حتى يتم ترقية كافة العقد.
  • لتعطيل ODE، قم بتعيين EnableOptimisticDirectExecution إلى false في QueryRequestOptions.
  • تمكين ODE كجزء من النشر الثاني لجميع العقد.

استخدام إنشاء خطة الاستعلام المحلية

تتضمن SQL SDK ServiceInterop.dll أصلية لتحليل الاستعلامات وتحسينها محليا. يتم دعمServiceInterop.dll فقط على نظام Windows x64 . تستخدم الأنواع التالية من التطبيقات معالجة مضيف 32 بت بشكل افتراضي. لتغيير معالجة المضيف إلى معالجة 64 بت، اتبع هذه الخطوات، حسب نوع التطبيق المستخدم:

  • بالنسبة للتطبيقات القابلة للتنفيذ، يمكنك تغيير معالجة المضيف عن طريق تعيين هدف النظام الأساسي إلى x64 في نافذة خصائص المشروع، في علامة التبويب البنية.

  • بالنسبة لمشروعات الاختبار المستندة إلى VSTest، يمكنك تغيير معالجة المضيف عن طريق تحديد اختبار>إعدادات الاختبار>بنية المعالج الافتراضية مثل X64 في قائمة الاختبار في Visual Studio.

  • بالنسبة لتطبيقات الويب ASP.NET المُستخدمة محليًّا، يمكنك تغيير معالجة المضيف عن طريق تحديد استخدام الإصدار 64 بت من IIS Express لمواقع الويب والمشروعات ضمن الأدوات>الخيارات>المشروعات والحلول>مشروعات الويب.

  • بالنسبة لتطبيقات الويب ASP.NET المُستخدمة على Azure، يمكنك تغيير معالجة المضيف عن طريق تحديد النظام الأساسي 64 بت في إعدادات التطبيق في مدخل Azure.

إشعار

تُعيَن مشروعات Visual Studio الجديدة على أي وحدة معالجة مركزية افتراضياً. نوصي بتعيين مشروعك على x64 حتى لا يتحول إلى x86. يمكن أن يتحول مشروع معين على أي وحدة معالجة مركزية بسهولة إلى x86 في حالة إضافة تبعية x86 فقط.

يجب أن يكونServiceInterop.dll في المجلد الذي يتم تنفيذ DLL SDK منه. لا ينبغي القلق بشأن هذا إلا في حالة نسخ ملفات DLL يدويًّا، أو وجود أنظمة إنشاء/استخدام مخصصة فقط.

استخدام استعلامات قسم واحد

بالنسبة للاستعلامات التي تستهدف مفتاح قسم عن طريق تعيين خاصية PartitionKey في QueryRequestOptions ولا تحتوي على تجميعات (بما في ذلك Distinct أو DCount أو Group By). في هذا المثال، تتم تصفية حقل مفتاح القسم الخاص /state بالقيمة Washington.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle' AND c.state = 'Washington'"
{
    // ...
}

اختياريا، يمكنك توفير مفتاح القسم كجزء من كائن خيارات الطلب.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    // ...
}

مهم

على الأجهزة العميلة التي تعمل بنظام تشغيل غير Windows، مثل Linux وmacOS، يجب دائما تحديد مفتاح القسم في كائن خيارات الطلب.

إشعار

تتطلب الاستعلامات عبر الأقسام SDK لزيارة جميع الأقسام الموجودة للتحقق من النتائج. كلما زادت الأقسام المادية التي تحتوي عليها الحاوية، كان من المحتمل أن تكون أبطأ.

تجنب إعادة إنشاء المكرر دون داعٍ

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

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    while (feedIterator.HasMoreResults) 
    {
        foreach(MyItem document in await feedIterator.ReadNextAsync())
        {
            // Iterate through documents
        }
    }
}

ضبط درجة التوازي

بالنسبة إلى الاستعلامات، اضبط الخاصية MaxConcurrency في QueryRequestOptions لتحديد أفضل التكوينات لتطبيقك، خاصةً إذا كنت تجري استعلامات عبر الأقسام (دون عامل تصفية على قيمة مفتاح القسم). MaxConcurrency يتحكم في الحد الأقصى لعدد المهام المتوازية، أي الحد الأقصى من الأقسام التي يجب زيارتها على نحوٍ متوازٍ. يتيح تعيين القيمة إلى -1 لحزمة تطوير البرامج (SDK) تحديد التزامن الأمثل.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxConcurrency = -1 }))
{
    // ...
}

لنفترض أن:

  • D = الحد الأقصى الافتراضي لعدد المهام المتوازية (= إجمالي عدد المعالجات في جهاز العميل)
  • P = العدد الأقصى المحدد من قبل المستخدم للمهام المتوازية
  • N = عدد الأقسام التي يجب زيارتها للإجابة عن استعلام

فيما يلي الآثار المترتبة على كيفية تصرف الاستعلامات المتوازية لقيم مختلفة من P.

  • (P == 0) => الوضع التسلسلي
  • (P == 1) => مهمة واحدة كحد أقصى
  • (P > 1) => Min (P، N) مهام متوازية
  • (P < 1) => المهام الموازية (N، D) كحد أدنى

ضبط حجم الصفحة

عند إصدار استعلام SQL، يتم إرجاع النتائج بطريقة مجزأة إذا كانت مجموعة النتائج كبيرة جداً.

إشعار

يجب عدم استخدام الخاصية MaxItemCount فقط لفصل الصفحات. استخدامها الرئيسي هو تحسين أداء الاستعلامات عن طريق تقليل الحد الأقصى لعدد العناصر التي تُعرَض في صفحة واحدة.

يمكنك أيضاً تعيين حجم الصفحة باستخدام أدوات SDK لـ Azure Cosmos DB المتوفرة. تسمح لك الخاصية MaxItemCount في QueryRequestOptions بتعيين الحد الأقصى لعدد العناصر التي تنتج في عملية التعداد. عند MaxItemCount الضبط على -1، تعثر SDK تلقائيا على القيمة المثلى، وفقا لحجم المستند. على سبيل المثال:

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxItemCount = 1000}))
{
    // ...
}

عند تنفيذ استعلام، تُرسَل البيانات الناتجة ضمن حزمة TCP. إذا حددت قيمة منخفضة جداً لـ MaxItemCount، فإن عدد الانتقالات المطلوبة لإرسال البيانات في داخل حزمة TCP يكون مرتفعاً، وهو ما يؤثر في الأداء. لذلك إذا لم تكن متأكدا من القيمة التي يجب تعيينها للخاصية MaxItemCount ، فمن الأفضل ضبطها على -1 والسماح لحزمة تطوير البرامج (SDK) باختيار القيمة التلقائية.

ضبط حجم المخزن المؤقت

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

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxBufferedItemCount = -1}))
{
    // ...
}

يعمل الجلب المسبق بنفس الطريقة بغض النظر عن درجة التوازي ، وهناك مخزن مؤقت واحد للبيانات من جميع الأقسام.

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

لمعرفة المزيد عن الأداء باستخدام .NET SDK:

تقليل استدعاءات خطة الاستعلام

لتنفيذ استعلام، يجب إنشاء خطة استعلام. تضيف طلبات الشبكة إلى بوابة Azure Cosmos DB إلى زمن انتقال عملية الاستعلام.

استخدام التخزين المؤقت لخطة الاستعلام

تُخزَّن خطة الاستعلام، لاستعلام تم تحديد نطاقه إلى قسم واحد، مؤقتاً على العميل. هذا يلغي الحاجة إلى إجراء مكالمة إلى البوابة لاسترداد خطة الاستعلام بعد المكالمة الأولى. مفتاح خطة الاستعلام المُخزَّنة مؤقتاً هو سلسلة استعلام SQL. تحتاج إلى التأكد من أن الاستعلام معلمي. إذا لم يكن الأمر كذلك، فغالبا ما يكون البحث عن ذاكرة التخزين المؤقت لخطة الاستعلام مفقودا لذاكرة التخزين المؤقت حيث من غير المرجح أن تكون سلسلة الاستعلام متطابقة عبر المكالمات. يتم تمكين التخزين المؤقت لخطة الاستعلام بشكل افتراضي ل Java SDK الإصدار 4.20.0 والإصدارات الأحدث ول Spring Data Azure Cosmos DB SDK الإصدار 3.13.0 والإصدارات الأحدث.

استخدام استعلامات القسم الواحد المُطابق للمعلمات

بالنسبة للاستعلامات ذات المعلمات التي يتم تحديد نطاقها إلى مفتاح قسم مع setPartitionKey في CosmosQueryRequestOptions ولا تحتوي على تجميعات (بما في ذلك Distinct أو DCount أو Group By) ، يمكن تجنب خطة الاستعلام:

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));

ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
paramList.add(new SqlParameter("@city", "Seattle"));
SqlQuerySpec querySpec = new SqlQuerySpec(
        "SELECT * FROM c WHERE c.city = @city",
        paramList);

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

إشعار

تتطلب الاستعلامات عبر الأقسام SDK لزيارة جميع الأقسام الموجودة للتحقق من النتائج. كلما زادت الأقسام المادية التي تحتوي عليها الحاوية، كان من المحتمل أن تكون أبطأ.

ضبط درجة التوازي

تعمل الاستعلامات المتوازية عن طريق الاستعلام عن أقسام متعددة بالتوازي. ومع ذلك، يتم جلب البيانات من حاوية مقسَّمة فردية بشكل تسلسلي فيما يتعلق بالاستعلام. لذا، استخدم setMaxDegreeOfParallelism على CosmosQueryRequestOptions لتعيين القيمة على عدد الأقسام لديك. إذا كنت لا تعرف عدد الأقسام، يمكنك استخدام setMaxDegreeOfParallelism لتعيين رقم كبير، ويختار النظام الحد الأدنى (عدد الأقسام، المدخلات المقدمة من المستخدم) كأقصى درجة للتوازي. يتيح تعيين القيمة إلى -1 لحزمة تطوير البرامج (SDK) تحديد التزامن الأمثل.

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

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxDegreeOfParallelism(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

لنفترض أن:

  • D = الحد الأقصى الافتراضي لعدد المهام المتوازية (= إجمالي عدد المعالجات في جهاز العميل)
  • P = العدد الأقصى المحدد من قبل المستخدم للمهام المتوازية
  • N = عدد الأقسام التي يجب زيارتها للإجابة عن استعلام

فيما يلي الآثار المترتبة على كيفية تصرف الاستعلامات المتوازية لقيم P المختلفة:

  • (P == 0) => الوضع التسلسلي
  • (P == 1) => مهمة واحدة كحد أقصى
  • (P > 1) => Min (P، N) مهام متوازية
  • (P == -1) => المهام الموازية (N, D) كحد أدنى

ضبط حجم الصفحة

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

يمكنك استخدام المعلمة pageSize في iterableByPage() لواجهة برمجة تطبيقات المتزامنة و byPage() لواجهة برمجة التطبيقات غير المتزامنة، لتحديد حجم الصفحة:

//  Sync API
Iterable<FeedResponse<MyItem>> filteredItemsAsPages =
    container.queryItems(querySpec, options, MyItem.class).iterableByPage(continuationToken,pageSize);

for (FeedResponse<MyItem> page : filteredItemsAsPages) {
    for (MyItem item : page.getResults()) {
        //...
    }
}

//  Async API
Flux<FeedResponse<MyItem>> filteredItemsAsPages =
    asyncContainer.queryItems(querySpec, options, MyItem.class).byPage(continuationToken,pageSize);

filteredItemsAsPages.map(page -> {
    for (MyItem item : page.getResults()) {
        //...
    }
}).subscribe();

ضبط حجم المخزن المؤقت

تم تصميم الاستعلام المتوازي للجلب المسبق للنتائج أثناء معالجة الدفعة الحالية من النتائج بواسطة العميل. يساعد الجلب المسبق في تحسين زمن الانتقال الكلي للاستعلام. setMaxBufferedItemCount في CosmosQueryRequestOptions يحد من عدد النتائج التي تم إحضارها مسبقا. لزيادة الجلب المسبق إلى أقصى حد، قم بتعيين الزر maxBufferedItemCount إلى رقم أعلى من ( pageSize ملاحظة: يمكن أن يؤدي ذلك أيضا إلى استهلاك ذاكرة مرتفع). لتقليل الجلب المسبق، اضبط الزر maxBufferedItemCount يساوي pageSize. إذا قمت بتعيين هذه القيمة إلى 0، فسيحدد النظام تلقائيا عدد العناصر المراد تخزينها مؤقتا.

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxBufferedItemCount(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

يعمل الجلب المسبق بنفس الطريقة بغض النظر عن درجة التوازي ، وهناك مخزن مؤقت واحد للبيانات من جميع الأقسام.

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

لمعرفة المزيد عن الأداء باستخدام Java SDK:

تقليل استدعاءات خطة الاستعلام

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

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington"
    )

ضبط حجم الصفحة

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

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington",
        max_item_count=1000
    )

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

لمعرفة المزيد حول استخدام Python SDK لواجهة برمجة التطبيقات ل NoSQL:

تقليل استدعاءات خطة الاستعلام

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

استخدام تعبير استعلام معلمات وتحديد مفتاح القسم في عبارة الاستعلام. يتكون الاستعلام برمجيا إلى SELECT * FROM todo t WHERE t.partitionKey = 'Bikes, Touring Bikes':

// find all items with same categoryId (partitionKey)
const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: "Bikes, Touring Bikes"
        }
    ]
};

// Get items 
const { resources } = await container.items.query(querySpec).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

أو حدد partitionKey في FeedOptions وتمريره كوسيطة:

const querySpec = {
    query: "select * from products p"
};

const { resources } = await container.items.query(querySpec, { partitionKey: "Bikes, Touring Bikes" }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

ضبط حجم الصفحة

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

const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: items[2].categoryId
        }
    ]
};

const { resources } = await container.items.query(querySpec, { maxItemCount: 1000 }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

التحكم المحسن في الاستعلام

بالنسبة إلى الإصدار 4.3.0 من Cosmos DB JS SDK والإصدارات الأحدث، enableQueryControl تم تقديم العلم، والذي يوفر تحكما أكبر في تنفيذ الاستعلام، مما يوفر مزيدا من المرونة في إدارة استهلاك وحدة الطلب (RU).

بشكل افتراضي، enableQueryControl يتم تعيين إلى false وتضمن SDK أن كل fetchNext استدعاء سيرجع maxItemCount عدد النتائج، شريطة وجود العديد من النتائج في النهاية الخلفية. ولكن لتلبية عدد النتائج المضمونة، قد تستعلم SDK عن أقسام الواجهة الخلفية عدة مرات في تكرار واحد fetchNext . يمكن أن يؤدي هذا في بعض الأحيان إلى زمن انتقال غير متوقع واستنزاف وحدة الطلب مع عدم وجود عنصر تحكم المستخدم، خاصة عندما تكون النتائج مبعثرة عبر الأقسام.

عند enableQueryControl التعيين إلى true، تستعلم كل fetchNext مكالمة الآن حتى maxDegreeOfParallelism الأقسام الفعلية. إذا لم يتم العثور على نتائج أو لم تكن النتائج جاهزة للعرض بعد، تقوم حزمة تطوير البرامج (SDK) بإرجاع الصفحات الفارغة بدلا من الاستمرار في البحث في جميع الأقسام في الخلفية. بهذه الطريقة، يحصل المستخدمون على تحكم أدق في تنفيذ الاستعلام الخاص بهم مع زمن انتقال يمكن التنبؤ به وبيانات استهلاك RU دقيقة.

const options = {
  enableQueryControl: true, // Flag to enable new query pipeline.
  maxItemCount: 100,
  maxDegreeOfParallelism: 6
};

const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: items[2].categoryId
        }
    ]
};
const queryIterator = container.items.query(querySpec, options);
// use this iterator to fetch results.

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

لمعرفة المزيد حول استخدام Node.js SDK لواجهة برمجة التطبيقات ل NoSQL: