لحن الأداء مع مشاهد متجسدة

تلميح

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

توفر العروض المادية لتجمعات SQL المخصصة في Azure Synapse طريقة منخفضة الصيانة لتحقيق أداء سريع للاستعلامات التحليلية المعقدة دون أي تغيير في الاستعلام. تناقش هذه المقالة الإرشادات العامة حول استخدام الآراء المتجسدة.

الرؤى المتجسدة مقابل الرؤى القياسية

تجمع SQL مخصص في Azure Synapse يدعم العروض القياسية والمؤثرة. كلاهما جداول افتراضية تم إنشاؤهما باستخدام تعبيرات SELECT وعرضت على الاستعلامات كجداول منطقية. تجمع العروض تعقيد الحوسبة الشائعة للبيانات وتضيف طبقة تجريدية إلى تغييرات الحوسبة، فلا حاجة لإعادة كتابة الاستعلامات.

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

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

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

المقارنه عرض عرض مادي
تعريف طريقة العرض مخزنة في مجموعة SQL مخصصة. مخزنة في مجموعة SQL مخصصة.
عرض المحتوى يتم إنشاؤه في كل مرة يتم فيها استخدام العرض. تمت معالجتها مسبقا وتخزينها في تجمع SQL مخصص أثناء إنشاء العرض. يتم التحديث مع إضافة البيانات إلى الجداول الأساسية.
تحديث البيانات دائما محدثة دائما محدثة
السرعة لاسترجاع بيانات العرض من الاستعلامات المعقدة بطيء صوم
تخزين إضافي لا. ‏‏نعم‬
بناء الجملة إنشاء طريقة عرض قاعدة بيانات إنشاء عرض مادي كاختيار

فوائد استخدام الرؤى المادية

يوفر المنظور المادي المصمم بشكل صحيح الفوائد التالية:

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

توفر العروض المادية المنفذة في مجموعة SQL المخصصة أيضا الفوائد التالية:

مقارنة بمزودي مستودعات البيانات الآخرين، توفر العروض المادية المنفذة في تجمع SQL المخصص الفوائد التالية:

  • دعم الدوال المجمعة بشكل عام. انظر إنشاء عرض مادي كخيار (Transact-SQL).
  • دعم التوصية بعرض مادي خاص بالاستعلام. انظر الشرح (Transact-SQL).
  • تحديث البيانات التلقائي والمتزامن مع تغييرات البيانات في جداول القاعدة. لا يتطلب الأمر أي إجراء من المستخدم.

السيناريوهات الشائعة

عادة ما تستخدم الرؤى المادية في السيناريوهات التالية:

الحاجة لتحسين أداء الاستعلامات التحليلية المعقدة مقابل البيانات الكبيرة الحجم

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

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

أحتاج أداء أسرع بدون تغييرات أو مع أقل تغييرات في الاستعلام

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

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

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

نحتاج إلى استراتيجية توزيع بيانات مختلفة لأداء استعلام أسرع

تجمع SQL المخصص هو نظام معالجة استعلامات موزعة. يتم توزيع البيانات في جدول SQL حتى 60 عقدة باستخدام واحدة من ثلاث استراتيجيات توزيع (التجزئة، round_robin، أو التكرار).

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

إرشادات التصميم

إليك الإرشادات العامة حول استخدام العروض المادية لتحسين أداء الاستعلام:

صمم لتناسب عبء عملك

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

يمكن للمستخدمين اللعب EXPLAIN WITH_RECOMMENDATIONS <SQL_statement> للحصول على العروض المادية التي يوصي بها محسن الاستعلام. نظرا لأن هذه التوصيات خاصة بالاستعلام، فقد لا يكون المنظور المادي الذي يفيد استعلاما واحدا مثاليا للاستعلامات الأخرى التي تضع نفس عبء العمل.

قيم هذه التوصيات مع مراعاة احتياجات عبء العمل لديك. الرؤى المتجسدة المثالية هي تلك التي تفيد أداء عبء العمل.

كن واعيا للمقايضة بين الاستعلامات الأسرع والتكلفة

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

يزداد عبء أعمال الصيانة عندما يزداد عدد العروض المحققة وتغييرات الجداول الأساسية. يجب على المستخدمين التحقق مما إذا كان يمكن تعويض التكلفة المتكبدة من جميع العروض المادية بزيادة أداء الاستعلام.

يمكنك تشغيل هذا الاستعلام لإنشاء قائمة بالعروض المادية في مجموعة SQL مخصصة:

SELECT V.name as materialized_view, V.object_id
FROM sys.views V
JOIN sys.indexes I ON V.object_id= I.object_id AND I.index_id < 2;

خيارات لتقليل عدد المشاهدات المحققة:

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

  • تخلص من العروض المادية التي تستخدم قليلا أو لم تعد ضرورية. لا يتم صيانة الرؤية المادية المعطلة لكنها لا تزال تتحمل تكاليف تخزين.

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


-- Query 1 would benefit from having a materialized view created with this SELECT statement

SELECT A, SUM(B)
FROM T
GROUP BY A

-- Query 2 would benefit from having a materialized view created with this SELECT statement

SELECT C, SUM(D)
FROM T
GROUP BY C

-- You could create a single materialized view of this form

SELECT A, C, SUM(B), SUM(D)
FROM T
GROUP BY A, C

ليس كل ضبط الأداء يتطلب تغيير الاستعلام

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

مراقبة الرؤى المتجسدة

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

لتجنب تدهور أداء الاستعلام، من الجيد تشغيل DBCC PDW_SHOWMATERIALIZEDVIEWOVERHEAD لمراقبة overhead_ratio العرض (total_rows / max(1, base_view_row)). يجب على المستخدمين إعادة بناء العرض المادي إذا كان overhead_ratio مرتفعا جدا.

الرؤية المتجسدة وتخزين مجموعة النتائج

تستخدم هاتان الميزتان في مجموعة SQL المخصصة لضبط أداء الاستعلام. يستخدم التخزين المؤقت لمجموعات النتائج للحصول على التزامن العالي والاستجابة السريعة من الاستعلامات المتكررة ضد البيانات الثابتة.

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

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

مثال

يستخدم هذا المثال استعلاما شبيها ب TPCDS للعثور على العملاء الذين ينفقون أموالا أكثر عبر الكتالوج مقارنة بالمتاجر، ويحدد العملاء المفضلين وبلدهم/منطقتهم الأصلية. يتضمن الاستعلام اختيار أفضل 100 سجل من اتحاد ثلاثة عبارات فرعية SELECT تشمل SUM() وGROUP BY.

WITH year_total AS (
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(ss_ext_list_price-ss_ext_wholesale_cost-ss_ext_discount_amt+ss_ext_sales_price, 0)/2) year_total
       ,'s' sale_type
FROM customer
     ,store_sales
     ,date_dim
WHERE c_customer_sk = ss_customer_sk
   AND ss_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year
UNION ALL
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(cs_ext_list_price-cs_ext_wholesale_cost-cs_ext_discount_amt+cs_ext_sales_price, 0)/2) year_total
       ,'c' sale_type
FROM customer
     ,catalog_sales
     ,date_dim
WHERE c_customer_sk = cs_bill_customer_sk
   AND cs_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year
UNION ALL
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(ws_ext_list_price-ws_ext_wholesale_cost-ws_ext_discount_amt+ws_ext_sales_price, 0)/2) year_total
       ,'w' sale_type
FROM customer
     ,web_sales
     ,date_dim
WHERE c_customer_sk = ws_bill_customer_sk
   AND ws_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year
         )
  SELECT TOP 100
                  t_s_secyear.customer_id
                 ,t_s_secyear.customer_first_name
                 ,t_s_secyear.customer_last_name
                 ,t_s_secyear.customer_birth_country
FROM year_total t_s_firstyear
     ,year_total t_s_secyear
     ,year_total t_c_firstyear
     ,year_total t_c_secyear
     ,year_total t_w_firstyear
     ,year_total t_w_secyear
WHERE t_s_secyear.customer_id = t_s_firstyear.customer_id
   AND t_s_firstyear.customer_id = t_c_secyear.customer_id
   AND t_s_firstyear.customer_id = t_c_firstyear.customer_id
   AND t_s_firstyear.customer_id = t_w_firstyear.customer_id
   AND t_s_firstyear.customer_id = t_w_secyear.customer_id
   AND t_s_firstyear.sale_type = 's'
   AND t_c_firstyear.sale_type = 'c'
   AND t_w_firstyear.sale_type = 'w'
   AND t_s_secyear.sale_type = 's'
   AND t_c_secyear.sale_type = 'c'
   AND t_w_secyear.sale_type = 'w'
   AND t_s_firstyear.dyear+0 =  1999
   AND t_s_secyear.dyear+0 = 1999+1
   AND t_c_firstyear.dyear+0 =  1999
   AND t_c_secyear.dyear+0 =  1999+1
   AND t_w_firstyear.dyear+0 = 1999
   AND t_w_secyear.dyear+0 = 1999+1
   AND t_s_firstyear.year_total > 0
   AND t_c_firstyear.year_total > 0
   AND t_w_firstyear.year_total > 0
   AND CASE WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total ELSE NULL END
           > CASE WHEN t_s_firstyear.year_total > 0 THEN t_s_secyear.year_total / t_s_firstyear.year_total ELSE NULL END
   AND CASE WHEN t_c_firstyear.year_total > 0 THEN t_c_secyear.year_total / t_c_firstyear.year_total ELSE NULL END
           > CASE WHEN t_w_firstyear.year_total > 0 THEN t_w_secyear.year_total / t_w_firstyear.year_total ELSE NULL END
ORDER BY t_s_secyear.customer_id
         ,t_s_secyear.customer_first_name
         ,t_s_secyear.customer_last_name
         ,t_s_secyear.customer_birth_country
OPTION ( LABEL = 'Query04-af359846-253-3');

تحقق من خطة التنفيذ المقدرة للاستفسار. هناك 18 عملية خلط و17 عملية انضمام، والتي تستغرق وقتا أطول للتنفيذ. الآن دعونا ننشئ عرضا متجسدا واحدا لكل من عبارات SELECT الفرعية الثلاثة.

CREATE materialized view nbViewSS WITH (DISTRIBUTION=HASH(customer_id)) AS
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(ss_ext_list_price-ss_ext_wholesale_cost-ss_ext_discount_amt+ss_ext_sales_price, 0)/2) year_total
          , count_big(*) AS cb
FROM dbo.customer
     ,dbo.store_sales
     ,dbo.date_dim
WHERE c_customer_sk = ss_customer_sk
   AND ss_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year
GO
CREATE materialized view nbViewCS WITH (DISTRIBUTION=HASH(customer_id)) AS
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(cs_ext_list_price-cs_ext_wholesale_cost-cs_ext_discount_amt+cs_ext_sales_price, 0)/2) year_total
          , count_big(*) as cb
FROM dbo.customer
     ,dbo.catalog_sales
     ,dbo.date_dim
WHERE c_customer_sk = cs_bill_customer_sk
   AND cs_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year

GO
CREATE materialized view nbViewWS WITH (DISTRIBUTION=HASH(customer_id)) AS
SELECT c_customer_id customer_id
       ,c_first_name customer_first_name
       ,c_last_name customer_last_name
       ,c_preferred_cust_flag customer_preferred_cust_flag
       ,c_birth_country customer_birth_country
       ,c_login customer_login
       ,c_email_address customer_email_address
       ,d_year dyear
       ,sum(isnull(ws_ext_list_price-ws_ext_wholesale_cost-ws_ext_discount_amt+ws_ext_sales_price, 0)/2) year_total
          , count_big(*) AS cb
FROM dbo.customer
     ,dbo.web_sales
     ,dbo.date_dim
WHERE c_customer_sk = ws_bill_customer_sk
   AND ws_sold_date_sk = d_date_sk
GROUP BY c_customer_id
         ,c_first_name
         ,c_last_name
         ,c_preferred_cust_flag
         ,c_birth_country
         ,c_login
         ,c_email_address
         ,d_year

تحقق من خطة تنفيذ الاستعلام الأصلي مرة أخرى. الآن يتغير عدد الاتصالات من 17 إلى 5 ولا يوجد خلط. اختر أيقونة عملية التصفية في الخطة، حيث تظهر قائمة الإخراج البيانات من العروض المادية بدلا من الجداول الأساسية.

Plan_Output_List_with_Materialized_Views

مع العروض المادية، يعمل نفس الاستعلام أسرع دون تغيير في الكود.

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

لمزيد من نصائح التطوير، راجع نظرة عامة على تطوير تجمع SQL المخصص.