ضبط أداء استعلامات قاعدة البيانات متعددة الأبعاد

عندما تستخدم قاعدة بيانات متعددة الأبعاد كمصدر بيانات في Oracle Analytics، قد تواجه مشكلات أداء تؤدي إلى تكوين استعلامات متعددة الأبعاد (MDX) غير مثالية.

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

لأن كل حالة استخدام فريدة، على فريق التطوير لديك مراجعة الخيارات، وتحليل سجلات استعلام Oracle Analytics، وتحديد الخيار الأفضل لحالة الاستخدام لديك.

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

المنهجية

توصي Oracle بأن تقوم بالمهام التالية لتعزيز الأداء. من المهم فهم بنية استعلامات MDX بالإضافة إلى سجلات الاستعلامات التي يقوم Oracle Analytics بتكوينها.

  • تبسيط استعلامات MDX التي تم تكوينها.
  • تقليل عدد استعلامات MDX التي تم تكوينها.
  • تأكد من تطبيق التحديدات والمرشحات المثالية في استعلام MDX.
  • ضبط الأداء لدى مسؤول قاعدة البيانات (DBA) من جانب قاعدة البيانات متعددة الأبعاد والتحقق من سبب استمرار سوء أداء قاعدة البيانات المصدر.
  • تعديل التحليل بناءً على تعليقات مسؤول قاعدة البيانات.

تحسين خطوات التحديد

عند تحسين خطوات التحديد، يمكنك تبسيط استعلامات MDX لديك، وتقليل عدد استعلامات MDX التي تم تكوينها، وتعزيز الأداء.

يعرض الشكل التالي مثالاً لمقارنة خطوات التحديد المحسنة وغير المحسنة.

فيما يلي وصف GUID-43E6F348-B14C-40DC-8C21-DA34DAE44344-default.jpg
.jpg

جمل CASE

لا يتم دعم وظيفة جملة CASE في استعلامات MDX ويجب تطبيقها دائمًا في Oracle Analytics. المنطق الموضح في هذا القسم فيما يتعلق بجمل CASE صالح لأغلب الوظائف غير المدعومة في استعلامات MDX (if null، وغيرها).

توجد ميزات وعيوب عند استخدام جمل CASE. عند تضمين جمل CASE في معادلات التقرير، لا يتم تضمينها في استعلام MDX. يمكن أن يؤدي ذلك إلى تبسيط استعلام MDX وتحسين الأداء. ومع ذلك، فإن المفاضلة هي أنه لا يمكنك الترشيح بشكل فعال مما يعني أن الاستعلام قد يُرجع سجلات أكثر مما هو ضروري.

فيما يلي قيود استخدام وظيفة جملة CASE:

  • إذا لم تجمع جملة CASE عدة أعضاء، يجب تضمين العمود الأساسي المستخدم في الجمل في الاستعلام وطريقة العرض كعمود منفصل مخفٍ.
  • إذا كانت جملة CASE تجمع عدة أعضاء، فلا يمكن تضمين العمود الأساسي في طريقة العرض بدون التأثير على مستوى التجميع. إذا كانت هذه هي الحالة:
    • إذا لم تكن قاعدة قياس التجميع هي التجميع الخارجي، فيجب استبعاد العمود الأساسي من الاستعلام.
    • إذا كانت قاعدة تجميع القياس التجميع الخارجي، يجب تضمين العمود الأساسي في الاستعلام واستثناؤه من طريقة العرض. يجب تغيير قاعدة التجميع للقياس من الافتراضية إلى قاعدة تجميع داخلية بسيطة (SUM، MAX، MIN). لا يعمل هذا إلا إذا تم استخدام قاعدة التجميع الداخلي لجمع الأعضاء وتقديم النتائج الصحيحة.

وظيفة FILTER

على عكس وظيفة جملة CASE، يمكن شحن وظيفة FILTER إلى قاعدة البيانات لتنفيذها.

الميزة الأساسية لاستخدام وظيفة FILTER في دوال التقرير هي أنه يتم تطبيق التحديد في استعلام MDX ويتم تقليل حجم البيانات المحتسبة واستعادتها من قاعدة البيانات.

العيب الأساسي لاستخدام وظيفة FILTER هو أنه قد يزيد عدد استعلامات MDX التي يتم تنفيذها. افتراضيًا، يتم تنفيذ استعلام واحد فقط لكل وظيفة FILTER مستخدمة.

مثال CASE مقابل FILTER

في هذا المثال، يطلب مستخدم تقريرًا يعرض الربح حسب ربع السنة ووحدة SKU للمنتج المحددة. بالإضافة إلى ذلك، يتم تجميع وحدات SKU معًا في 12 فئة. تحتوي الفئة "الكولا الأخرى" على منتجات مجال العمل التالية المعينة: الكولا، ودايت كولا، ودايت كولا المشتركة.

فيما يلي وصف GUID-7198F143-54E6-4A48-9579-96624936A94D-default.jpg
.jpg

فيما يلي الاستعلام المنطقي لجملة CASE:

SELECT

   0 s_0,

   CASE when XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Cola','Diet Cola','Shared Diet Cola') THEN 'Other Cola' ELSE XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" END s_1,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_2,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_3,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_4,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_5,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_6,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_7,

   XSA('Admin'.'Sample.BasicPM')."Product"."Category" s_8,

   XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" s_9,

   XSA('Admin'.'Sample.BasicPM')."Year"."Quarter" s_10,

   XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" s_11

FROM XSA('Admin'.'Sample.BasicPM')

ORDER BY 8 ASC NULLS LAST, 11 ASC NULLS LAST, 5 ASC NULLS LAST, 2 ASC NULLS LAST, 7 ASC NULLS LAST, 10 ASC NULLS LAST, 4 ASC NULLS LAST, 6 ASC NULLS LAST, 9 ASC NULLS LAST, 3 ASC NULLS LAST

FETCH FIRST 125001 ROWS ONLY

لا يوجد تجميع قائم على جملة CASE. يتم تكوين استعلام MDX بسيط، بجملة CASE تمت معالجتها بواسطة Oracle Analytics:

With 
  set [_Product3]  as 'Descendants([Product], [Product].Generations(3), leaves)'
  set [_Year2]  as 'Descendants([Year], [Year].Generations(2), leaves)'
select 
  { [Measures].[Profit]
  } on columns,
  NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties GEN_NUMBER, [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows 
from [Sample.Basic]

يتم تنفيذ جملة CASE على خادم BI Server ويتم عرض هذا بواسطة إعداد قاعدة البيانات المعين على database 0:0,0:

 RqList <<11777451>> [for database 0:0,0]
                            D1.c6 as c6 [for database 0:0,0],
                            D1.c4 as c4 [for database 0:0,0],
                            case  when D1.c7 in ([ 'Cola', 'Diet Cola', 'Shared Diet Cola'] ) then 'Other Cola' else D1.c7 end  as c2 [for database 0:0,0],
                            D1.c5 as c5 [for database 0:0,0],
                            D1.c3 as c3 [for database 0:0,0],
                            D1.c1 as c1 [for database 0:0,0],
                            D1.c7 as c7 [for database 0:0,0],
                            D1.c8 as c8 [for database 0:0,0]

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

فيما يلي الاستعلام المنطقي لجملة FILTER:

SELECT

   0 s_0,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_1,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_2,

   DESCRIPTOR_IDOF(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_3,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Category") s_4,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU") s_5,

   SORTKEY(XSA('Admin'.'Sample.BasicPM')."Year"."Quarter") s_6,

   XSA('Admin'.'Sample.BasicPM')."Product"."Category" s_7,

   XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" s_8,

   XSA('Admin'.'Sample.BasicPM')."Year"."Quarter" s_9,

   FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Cola','Diet Cola','Shared Diet Cola')) s_10,

   FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('Sasprilla','Birch Beer','Dark Cream')) s_11,

   FILTER(XSA('Admin'.'Sample.BasicPM')."Basic"."Profit" USING XSA('Admin'.'Sample.BasicPM')."Product"."Product SKU" in ('xxxxx')) s_12

FROM XSA('Admin'.'Sample.BasicPM')

ORDER BY 7 ASC NULLS LAST, 10 ASC NULLS LAST, 4 ASC NULLS LAST, 6 ASC NULLS LAST, 9 ASC NULLS LAST, 3 ASC NULLS LAST, 5 ASC NULLS LAST, 8 ASC NULLS LAST, 2 ASC NULLS LAST

FETCH FIRST 125001 ROWS ONLY

في هذا الاستعلام، توجد ثلاثة استعلامات، واحد لكل مرشح تم تكوينه، وتواجه مشكلات أداء.

الاستعلام 1:

With

  set [_Product3]  as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "xxxxx")))'

  set [_Year2]  as 'Descendants([Year], [Year].Generations(2), leaves)'

select

  { [Measures].[Profit]

  } on columns,

  NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows

from [Sample.Basic]

]]

الاستعلام 2:

With

  set [_Product3]  as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Birch Beer") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Dark Cream") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Sasprilla")))'

  set [_Year2]  as 'Descendants([Year], [Year].Generations(2), leaves)'

select

  { [Measures].[Profit]

  } on columns,

  NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows

from [Sample.Basic]

]]

الاستعلام 3:

With

  set [_Product3]  as 'Filter([Product].Generations(3).members, ((IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Cola") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Diet Cola") OR (IIF(IsValid([Product].CurrentMember.MEMBER_ALIAS), [Product].CurrentMember.MEMBER_ALIAS, [Product].CurrentMember.MEMBER_Name) = "Shared Diet Cola")))'

  set [_Year2]  as 'Descendants([Year], [Year].Generations(2), leaves)'

select

  { [Measures].[Profit]

  } on columns,

  NON EMPTY {crossjoin({[_Year2]},{[_Product3]})} properties MEMBER_NAME, GEN_NUMBER, property_expr([Product], [MEMBER_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category_Null_Alias_Replacement"), property_expr([Product], [Default], Ancestor(currentaxismember(), [Product].Generations(2)), "Category"), property_expr([Product], [MEMBER_UNIQUE_NAME], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Member Key"), property_expr([Product], [Memnor], Ancestor(currentaxismember(), [Product].Generations(2)), "Category - Memnor"), [Product].[MEMBER_UNIQUE_NAME], [Product].[Memnor], [Year].[MEMBER_UNIQUE_NAME], [Year].[Memnor] on rows

from [Sample.Basic]

مثال على مرشح منتج مطبق

الأسلوب الأفضل هو تضمين عمود المنتج في التقرير بعمود قياس جديد بدون مرشح. ثم قم بتكوين مرشح يتضمن المنتجات اللازمة. إذا كنت تريد تجميع المنتجات في فئات مختلفة، فاستخدم جملة CASE. في هذا السيناريو، يتم تكوين استعلام MDX بالصفوف التي تم ترشيحها وبالرغم من تطبيق CASE بواسطة Oracle Analytics، فهو يستخدم المجموعة الفرعية من البيانات وليس كل السجلات.

هذا سيناريو آخر حيث تسبب جمل CASE مشكلات الأداء.

يطبق المطور جملة CASE لإعادة تسمية العلامات التجارية، ويتيح موجه لوحة المعلومات للمستخدمين تحديد العلامة التجارية.

فيما يلي وصف GUID-56356AA9-2AF6-4A67-8ADD-FC4F7F70306C-default.jpg
.jpg

فيما يلي وصف GUID-E63719C8-9936-412B-8228-F20E8F048C46-default.jpg
.jpg

لأن جملة CASE غير مدعومة في MDX، فلا يمكن تطبيق المرشح في Brand2 في استعلام MDX. يتم تحديد كل العلامات التجارية، وهذا ليس محسنًا.

فيما يلي وصف GUID-6BE1F274-8257-4E31-8D42-406357A07B2A-default.jpg
.jpg

في هذا النوع من السيناريو، توصي Oracle بإزالة جملة CASE وإعادة تسمية الأعضاء في قاعدة البيانات أو تكوين أسماء مستعارة.