إدارة حِمل العمل باستخدام فئات الموارد في Azure Synapse Analytics

إرشادات لاستخدام فئات الموارد لإدارة الذاكرة والتزامن لاستعلامات تجمع Synapse SQL في Azure Synapse.

ما فئات الموارد

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

  • تعمل فئات الموارد الأصغر على تقليل الحد الأقصى للذاكرة لكل استعلام، ولكنها تزيد من التزامن.
  • تعمل فئات الموارد الأكبر على زيادة الحد الأقصى للذاكرة لكل استعلام، ولكنها تقلل التزامن.

هناك نوعان من فئات الموارد:

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

تستخدم فئات الموارد فتحات التزامن لقياس استهلاك الموارد. تم شرح فتحات التزامن لاحقاً في هذه المقالة.

فئات الموارد الثابتة

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

يتم تنفيذ فئات الموارد الثابتة باستخدام أدوار قواعد البيانات المحددة مسبقاً:

  • staticrc10
  • staticrc20
  • staticrc30
  • staticrc40
  • staticrc50
  • staticrc60
  • staticrc70
  • staticrc80

فئات الموارد الديناميكية

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

يتم تنفيذ فئات الموارد الديناميكية باستخدام أدوار قاعدة البيانات المحددة مسبقاً:

  • smallrc
  • mediumrc
  • largerc
  • xlargerc

تخصيص الذاكرة لكل فئة من فئات الموارد على النحو التالي.

مستوى الخدمة smallrc mediumrc largerc xlargerc
DW100c 25% 25% 25% ٪70
DW200c 12.5% 12.5% 22% ٪70
DW300c 8% 10% 22% ٪70
DW400c 6.25% 10% 22% ٪70
DW500c 5% 10% 22% ٪70
DW1000c إلى
DW30000c
3% 10% 22% ٪70

فئة الموارد الافتراضية

بشكل افتراضي، يكون كل مستخدم عضواً في فئة الموارد الديناميكية smallrc.

صنف المورد لمسؤول الخدمة ثابت في smallrc ولا يمكن تغييره. مسؤول الخدمة هو المستخدم الذي تم إنشاؤه أثناء عملية التوفير. مسؤول الخدمة في هذا السياق هو تسجيل الدخول المحدد لـ "تسجيل دخول مسؤول الخادم" عند إنشاء تجمع Synapse SQL جديد مع خادم جديد.

إشعار

المستخدمون أو المجموعات المحددة كمسؤول Active Directory هم أيضاً مسؤولو الخدمة.

عمليات فئة الموارد

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

العمليات التي تحكمها فئات الموارد

تخضع هذه العمليات لفئات الموارد:

  • INSERT-SELECT أو UPDATE أو DELETE
  • SELECT (عند الاستعلام عن جداول المستخدم)
  • ALTER INDEX - REBUILD أو REORGANIZE
  • ALTER TABLE REBUILD
  • إنشاء فهرس
  • CREATE CLUSTERED COLUMNSTORE INDEX
  • إنشاء جدول كما هو محدد (CTAS)
  • تحميل البيانات
  • عمليات نقل البيانات التي تجريها خدمة نقل البيانات (DMS)

إشعار

لا تخضع عبارات SELECT الخاصة بعروض الإدارة الديناميكية (DMVs) أو طرق عرض النظام الأخرى لأي من حدود التزامن. يمكنك مراقبة النظام بغض النظر عن عدد الاستعلامات المنفذة عليه.

العمليات التي لا تحكمها فئات الموارد

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

العبارات التالية مستثناة من فئات الموارد ويتم تشغيلها دائماً في smallrc:

  • CREATE أو DROP TABLE
  • ALTER TABLE ... SWITCH أو SPLIT أو MERGE PARTITION
  • ALTER INDEX DISABLE
  • إسقاط فهرس
  • CREATE أو UPDATE أو DROP STATISTICS
  • اقتطاع جدول
  • ALTER AUTHORIZATION
  • CREATE LOGIN
  • CREATE أو ALTER أو DROP USER
  • CREATE أو ALTER أو DROP PROCEDURE
  • CREATE أو DROP VIEW
  • INSERT VALUES
  • حدد من عروض النظام وDMVs
  • EXPLAIN
  • DBCC

فتحات التزامن

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

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

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

عرض فئات الموارد

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

SELECT name
FROM   sys.database_principals
WHERE  name LIKE '%rc%' AND type_desc = 'DATABASE_ROLE';

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

يتم تنفيذ فئات الموارد من خلال تعيين المستخدمين لأدوار قاعدة البيانات. عندما يقوم المستخدم بتشغيل استعلام، يتم تشغيل الاستعلام مع فئة موارد المستخدم. على سبيل المثال، إذا كان المستخدم عضواً في دور قاعدة بيانات staticrc10، فإن استعلاماته تعمل بكميات صغيرة من الذاكرة. إذا كان مستخدم قاعدة البيانات عضواً في أدوار قاعدة البيانات xlargerc أو staticrc80، فإن استعلاماتهم تعمل بكميات كبيرة من الذاكرة.

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

EXEC sp_addrolemember 'largerc', 'loaduser';

لتقليل فئة المورد، استخدم sp_droprolemember. إذا لم يكن "loaduser" عضواً أو فئة من أي فئات موارد أخرى، فإنهم ينتقلون إلى فئة موارد smallrc الافتراضية مع منحة ذاكرة بنسبة 3%.

EXEC sp_droprolemember 'largerc', 'loaduser';

أسبقية فئة الموارد

يمكن للمستخدمين أن يكونوا أعضاء في فئات موارد متعددة. عندما ينتمي مستخدم إلى أكثر من فئة مورد:

  • تحظى فئات الموارد الديناميكية بالأولوية على فئات الموارد الثابتة. على سبيل المثال، إذا كان المستخدم عضواً في كل من mediumrc (ديناميكي) وstaticrc80 (ثابت)، يتم تشغيل الاستعلامات باستخدام mediumrc.
  • فئات الموارد الأكبر لها الأسبقية على فئات الموارد الأصغر. على سبيل المثال، إذا كان المستخدم عضواً في mediumrc وأكبر c، فإن الاستعلامات تعمل مع أكبر c. وبالمثل، إذا كان المستخدم عضواً في كل من staticrc20 وstatirc80، يتم تشغيل الاستعلامات مع تخصيصات موارد staticrc80.

التوصيات

إشعار

ضع في اعتبارك الاستفادة من إمكانات إدارة حِمل العمل (عزل حمل العملو التصنيف والأهمية) لمزيد من التحكم في حِمل العمل والأداء المتوقع.

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

فئات الموارد لمستخدمي التحميل

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

تعتمد الذاكرة اللازمة لمعالجة الأحمال بكفاءة على طبيعة الجدول الذي تم تحميله وحجم البيانات. لمزيد من المعلومات حول متطلبات الذاكرة، راجع زيادة جودة rowgroup.

بمجرد تحديد متطلبات الذاكرة، اختر ما إذا كنت تريد تعيين مستخدم التحميل إلى فئة مورد ثابت أو ديناميكي.

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

فئات الموارد للاستعلامات

بعض الاستعلامات كثيفة الحوسبة والبعض الآخر ليس كذلك.

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

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

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

تعليمة برمجية مثال للعثور على أفضل فئة الموارد

يمكنك استخدام الإجراء المخزن المحدد التالي لمعرفة منح التزامن والذاكرة لكل فئة مورد في SLO محدد وأفضل فئة موارد لعمليات CCI المكثفة للذاكرة على جدول CCI غير المقسم في فئة مورد معينة:

إليك الغرض من هذا الإجراء المخزن:

  1. لمشاهدة منح التزامن والذاكرة لكل فئة مورد في SLO معين. يحتاج المستخدم إلى توفير NULL لكل من المخطط واسم الجدول كما هو موضح في هذا المثال.
  2. لمشاهدة أفضل فئة موارد لعمليات CCI التي تستهلك الكثير من الذاكرة (تحميل، نسخ جدول، إعادة بناء فهرس، إلخ) على جدول CCI غير المقسم في فئة موارد معينة. يستخدم proc المخزن مخطط الجدول لمعرفة منحة الذاكرة المطلوبة.

التبعيات والقيود

  • لم يتم تصميم هذا الإجراء المخزن لحساب متطلبات الذاكرة لجدول cci مقسم.
  • لا يأخذ هذا الإجراء المخزن في الاعتبار متطلبات الذاكرة لجزء SELECT من CTAS/INSERT-SELECT ويفترض أنه SELECT.
  • يستخدم هذا الإجراء المخزن جدولاً مؤقتاً، والذي يتوفر في الجلسة حيث تم إنشاء هذا الإجراء المخزن.
  • يعتمد هذا الإجراء المخزن على العروض الحالية (على سبيل المثال، تكوين الأجهزة، تكوين DMS)، وإذا تغير أي من هذه التغييرات، فلن يعمل هذا proc المخزن بشكل صحيح.
  • يعتمد هذا الإجراء المخزن على عروض حد التزامن الحالية وإذا تغيرت، فلن يعمل هذا الإجراء المخزن بشكل صحيح.
  • يعتمد هذا الإجراء المخزن على عروض فئة الموارد الموجودة وإذا كانت هذه التغييرات، فلن يعمل هذا الإجراء المخزن بشكل صحيح.

إشعار

إذا لم تحصل على الإخراج بعد تنفيذ الإجراء المخزن مع توفير المعلمات، فقد تكون هناك حالتان.

  1. تحتوي إما معلمة DW على قيمة SLO غير صالحة
  2. أو، لا توجد فئة مورد مطابقة لعملية CCI على الجدول.

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

مثال على الاستخدام

بناء الجملة:
EXEC dbo.prc_workload_management_by_DWU @DWU VARCHAR(7), @SCHEMA_NAME VARCHAR(128), @TABLE_NAME VARCHAR(128)

  1. @DWU: إما توفير معلمة NULL لاستخراج DWU الحالي من DW DB أو توفير أي DWU مدعوم في شكل 'DW100c'
  2. @SCHEMA_NAME: أدخل اسم مخطط للجدول
  3. @TABLE_NAME: أدخل اسم جدول الاهتمام

أمثلة على تنفيذ هذا الإجراء المخزن:

EXEC dbo.prc_workload_management_by_DWU 'DW2000c', 'dbo', 'Table1';  
EXEC dbo.prc_workload_management_by_DWU NULL, 'dbo', 'Table1';  
EXEC dbo.prc_workload_management_by_DWU 'DW6000c', NULL, NULL;  
EXEC dbo.prc_workload_management_by_DWU NULL, NULL, NULL;  

تقوم العبارة التالية بإنشاء Table1 الذي يتم استخدامه في الأمثلة السابقة. CREATE TABLE Table1 (a int, b varchar(50), c decimal (18,10), d char(10), e varbinary(15), f float, g datetime, h date);

تعريف الإجراء المخزن

-------------------------------------------------------------------------------
-- Dropping prc_workload_management_by_DWU procedure if it exists.
-------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'prc_workload_management_by_DWU')
DROP PROCEDURE dbo.prc_workload_management_by_DWU
GO

-------------------------------------------------------------------------------
-- Creating prc_workload_management_by_DWU.
-------------------------------------------------------------------------------
CREATE PROCEDURE dbo.prc_workload_management_by_DWU
(@DWU VARCHAR(8),
 @SCHEMA_NAME VARCHAR(128),
 @TABLE_NAME VARCHAR(128)
)
AS

IF @DWU IS NULL
BEGIN
-- Selecting proper DWU for the current DB if not specified.

SELECT @DWU = 'DW'+ CAST(CASE WHEN Mem> 4 THEN Nodes*500
  ELSE Mem*100
  END AS VARCHAR(10)) +'c'
    FROM (
      SELECT Nodes=count(distinct n.pdw_node_id), Mem=max(i.committed_target_kb/1000/1000/60)
        FROM sys.dm_pdw_nodes n
        CROSS APPLY sys.dm_pdw_nodes_os_sys_info i
        WHERE type = 'COMPUTE')A
END

-- Dropping temp table if exists.
IF OBJECT_ID('tempdb..#ref') IS NOT NULL
BEGIN
  DROP TABLE #ref;
END;

-- Creating ref. temp table (CTAS) to hold mapping info.
CREATE TABLE #ref
WITH (DISTRIBUTION = ROUND_ROBIN)
AS
WITH
-- Creating concurrency slots mapping for various DWUs.
alloc
AS
(
SELECT 'DW100c' AS DWU,4 AS max_queries,4 AS max_slots,1 AS slots_used_smallrc,1 AS slots_used_mediumrc,2 AS slots_used_largerc,4 AS slots_used_xlargerc,1 AS slots_used_staticrc10,2 AS slots_used_staticrc20,4 AS slots_used_staticrc30,4 AS slots_used_staticrc40,4 AS slots_used_staticrc50,4 AS slots_used_staticrc60,4 AS slots_used_staticrc70,4 AS slots_used_staticrc80
  UNION ALL
   SELECT 'DW200c',8,8,1,2,4,8,1,2,4,8,8,8,8,8
  UNION ALL
   SELECT 'DW300c',12,12,1,2,4,8,1,2,4,8,8,8,8,8
  UNION ALL
   SELECT 'DW400c',16,16,1,4,8,16,1,2,4,8,16,16,16,16
  UNION ALL
   SELECT 'DW500c',20,20,1,4,8,16,1,2,4,8,16,16,16,16
  UNION ALL
   SELECT 'DW1000c',32,40,1,4,8,28,1,2,4,8,16,32,32,32
  UNION ALL
   SELECT 'DW1500c',32,60,1,6,13,42,1,2,4,8,16,32,32,32
  UNION ALL
   SELECT 'DW2000c',48,80,2,8,17,56,1,2,4,8,16,32,64,64
  UNION ALL
   SELECT 'DW2500c',48,100,3,10,22,70,1,2,4,8,16,32,64,64
  UNION ALL
   SELECT 'DW3000c',64,120,3,12,26,84,1,2,4,8,16,32,64,64
  UNION ALL
   SELECT 'DW5000c',64,200,6,20,44,140,1,2,4,8,16,32,64,128
  UNION ALL
   SELECT 'DW6000c',128,240,7,24,52,168,1,2,4,8,16,32,64,128
  UNION ALL
   SELECT 'DW7500c',128,300,9,30,66,210,1,2,4,8,16,32,64,128
  UNION ALL
   SELECT 'DW10000c',128,400,12,40,88,280,1,2,4,8,16,32,64,128
  UNION ALL
   SELECT 'DW15000c',128,600,18,60,132,420,1,2,4,8,16,32,64,128
  UNION ALL
   SELECT 'DW30000c',128,1200,36,120,264,840,1,2,4,8,16,32,64,128
)
-- Creating workload mapping to their corresponding slot consumption and default memory grant.
,map  
AS
(
  SELECT CONVERT(varchar(20), 'SloDWGroupSmall') AS wg_name, slots_used_smallrc AS slots_used FROM alloc WHERE DWU = @DWU
UNION ALL
  SELECT CONVERT(varchar(20), 'SloDWGroupMedium') AS wg_name, slots_used_mediumrc AS slots_used FROM alloc WHERE DWU = @DWU
UNION ALL
  SELECT CONVERT(varchar(20), 'SloDWGroupLarge') AS wg_name, slots_used_largerc AS slots_used FROM alloc WHERE DWU = @DWU
UNION ALL
  SELECT CONVERT(varchar(20), 'SloDWGroupXLarge') AS wg_name, slots_used_xlargerc AS slots_used FROM alloc WHERE DWU = @DWU
  UNION ALL
  SELECT 'SloDWGroupC00',1
  UNION ALL
    SELECT 'SloDWGroupC01',2
  UNION ALL
    SELECT 'SloDWGroupC02',4
  UNION ALL
    SELECT 'SloDWGroupC03',8
  UNION ALL
    SELECT 'SloDWGroupC04',16
  UNION ALL
    SELECT 'SloDWGroupC05',32
  UNION ALL
    SELECT 'SloDWGroupC06',64
  UNION ALL
    SELECT 'SloDWGroupC07',128
)

-- Creating ref based on current / asked DWU.
, ref
AS
(
  SELECT  a1.*
  ,       m1.wg_name          AS wg_name_smallrc
  ,       m1.slots_used * 250 AS tgt_mem_grant_MB_smallrc
  ,       m2.wg_name          AS wg_name_mediumrc
  ,       m2.slots_used * 250 AS tgt_mem_grant_MB_mediumrc
  ,       m3.wg_name          AS wg_name_largerc
  ,       m3.slots_used * 250 AS tgt_mem_grant_MB_largerc
  ,       m4.wg_name          AS wg_name_xlargerc
  ,       m4.slots_used * 250 AS tgt_mem_grant_MB_xlargerc
  ,       m5.wg_name          AS wg_name_staticrc10
  ,       m5.slots_used * 250 AS tgt_mem_grant_MB_staticrc10
  ,       m6.wg_name          AS wg_name_staticrc20
  ,       m6.slots_used * 250 AS tgt_mem_grant_MB_staticrc20
  ,       m7.wg_name          AS wg_name_staticrc30
  ,       m7.slots_used * 250 AS tgt_mem_grant_MB_staticrc30
  ,       m8.wg_name          AS wg_name_staticrc40
  ,       m8.slots_used * 250 AS tgt_mem_grant_MB_staticrc40
  ,       m9.wg_name          AS wg_name_staticrc50
  ,       m9.slots_used * 250 AS tgt_mem_grant_MB_staticrc50
  ,       m10.wg_name          AS wg_name_staticrc60
  ,       m10.slots_used * 250 AS tgt_mem_grant_MB_staticrc60
  ,       m11.wg_name          AS wg_name_staticrc70
  ,       m11.slots_used * 250 AS tgt_mem_grant_MB_staticrc70
  ,       m12.wg_name          AS wg_name_staticrc80
  ,       m12.slots_used * 250 AS tgt_mem_grant_MB_staticrc80
  FROM alloc a1
  JOIN map   m1  ON a1.slots_used_smallrc     = m1.slots_used and m1.wg_name = 'SloDWGroupSmall'
  JOIN map   m2  ON a1.slots_used_mediumrc    = m2.slots_used and m2.wg_name = 'SloDWGroupMedium'
  JOIN map   m3  ON a1.slots_used_largerc     = m3.slots_used and m3.wg_name = 'SloDWGroupLarge'
  JOIN map   m4  ON a1.slots_used_xlargerc    = m4.slots_used and m4.wg_name = 'SloDWGroupXLarge'
  JOIN map   m5  ON a1.slots_used_staticrc10    = m5.slots_used and m5.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m6  ON a1.slots_used_staticrc20    = m6.slots_used and m6.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m7  ON a1.slots_used_staticrc30    = m7.slots_used and m7.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m8  ON a1.slots_used_staticrc40    = m8.slots_used and m8.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m9  ON a1.slots_used_staticrc50    = m9.slots_used and m9.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m10  ON a1.slots_used_staticrc60    = m10.slots_used and m10.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m11  ON a1.slots_used_staticrc70    = m11.slots_used and m11.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  JOIN map   m12  ON a1.slots_used_staticrc80    = m12.slots_used and m12.wg_name NOT IN ('SloDWGroupSmall','SloDWGroupMedium','SloDWGroupLarge','SloDWGroupXLarge')
  WHERE   a1.DWU = @DWU
)
SELECT  DWU
,       max_queries
,       max_slots
,       slots_used
,       wg_name
,       tgt_mem_grant_MB
,       up1 as rc
,       (ROW_NUMBER() OVER(PARTITION BY DWU ORDER BY DWU)) as rc_id
FROM
(
    SELECT  DWU
    ,       max_queries
    ,       max_slots
    ,       slots_used
    ,       wg_name
    ,       tgt_mem_grant_MB
    ,       REVERSE(SUBSTRING(REVERSE(wg_names),1,CHARINDEX('_',REVERSE(wg_names),1)-1)) as up1
    ,       REVERSE(SUBSTRING(REVERSE(tgt_mem_grant_MBs),1,CHARINDEX('_',REVERSE(tgt_mem_grant_MBs),1)-1)) as up2
    ,       REVERSE(SUBSTRING(REVERSE(slots_used_all),1,CHARINDEX('_',REVERSE(slots_used_all),1)-1)) as up3
    FROM    ref AS r1
    UNPIVOT
    (
        wg_name FOR wg_names IN (wg_name_smallrc,wg_name_mediumrc,wg_name_largerc,wg_name_xlargerc,
        wg_name_staticrc10, wg_name_staticrc20, wg_name_staticrc30, wg_name_staticrc40, wg_name_staticrc50,
        wg_name_staticrc60, wg_name_staticrc70, wg_name_staticrc80)
    ) AS r2
    UNPIVOT
    (
        tgt_mem_grant_MB FOR tgt_mem_grant_MBs IN (tgt_mem_grant_MB_smallrc,tgt_mem_grant_MB_mediumrc,
        tgt_mem_grant_MB_largerc,tgt_mem_grant_MB_xlargerc, tgt_mem_grant_MB_staticrc10, tgt_mem_grant_MB_staticrc20,
        tgt_mem_grant_MB_staticrc30, tgt_mem_grant_MB_staticrc40, tgt_mem_grant_MB_staticrc50,
        tgt_mem_grant_MB_staticrc60, tgt_mem_grant_MB_staticrc70, tgt_mem_grant_MB_staticrc80)
    ) AS r3
    UNPIVOT
    (
        slots_used FOR slots_used_all IN (slots_used_smallrc,slots_used_mediumrc,slots_used_largerc,
        slots_used_xlargerc, slots_used_staticrc10, slots_used_staticrc20, slots_used_staticrc30,
        slots_used_staticrc40, slots_used_staticrc50, slots_used_staticrc60, slots_used_staticrc70,
        slots_used_staticrc80)
    ) AS r4
) a
WHERE   up1 = up2
AND     up1 = up3
;

-- Getting current info about workload groups.
WITH  
dmv  
AS  
(
  SELECT
          rp.name                                           AS rp_name
  ,       rp.max_memory_kb*1.0/1048576                      AS rp_max_mem_GB
  ,       (rp.max_memory_kb*1.0/1024)
          *(request_max_memory_grant_percent/100)           AS max_memory_grant_MB
  ,       (rp.max_memory_kb*1.0/1048576)
          *(request_max_memory_grant_percent/100)           AS max_memory_grant_GB
  ,       wg.name                                           AS wg_name
  ,       wg.importance                                     AS importance
  ,       wg.request_max_memory_grant_percent               AS request_max_memory_grant_percent
  FROM    sys.dm_pdw_nodes_resource_governor_workload_groups wg
  JOIN    sys.dm_pdw_nodes_resource_governor_resource_pools rp    ON  wg.pdw_node_id  = rp.pdw_node_id
                                                                  AND wg.pool_id      = rp.pool_id
  WHERE   rp.name = 'SloDWPool'
  GROUP BY
          rp.name
  ,       rp.max_memory_kb
  ,       wg.name
  ,       wg.importance
  ,       wg.request_max_memory_grant_percent
)
-- Creating resource class name mapping.
,names
AS
(
  SELECT 'smallrc' as resource_class, 1 as rc_id
  UNION ALL
    SELECT 'mediumrc', 2
  UNION ALL
    SELECT 'largerc', 3
  UNION ALL
    SELECT 'xlargerc', 4
  UNION ALL
    SELECT 'staticrc10', 5
  UNION ALL
    SELECT 'staticrc20', 6
  UNION ALL
    SELECT 'staticrc30', 7
  UNION ALL
    SELECT 'staticrc40', 8
  UNION ALL
    SELECT 'staticrc50', 9
  UNION ALL
    SELECT 'staticrc60', 10
  UNION ALL
    SELECT 'staticrc70', 11
  UNION ALL
    SELECT 'staticrc80', 12
)
,base AS
(   SELECT  schema_name
    ,       table_name
    ,       SUM(column_count)                   AS column_count
    ,       ISNULL(SUM(short_string_column_count),0)   AS short_string_column_count
    ,       ISNULL(SUM(long_string_column_count),0)    AS long_string_column_count
    FROM    (   SELECT  sm.name                                             AS schema_name
                ,       tb.name                                             AS table_name
                ,       COUNT(co.column_id)                                 AS column_count
                           ,       CASE    WHEN co.system_type_id IN (36,43,106,108,165,167,173,175,231,239)
                                AND  co.max_length <= 32
                                THEN COUNT(co.column_id)
                        END                                                 AS short_string_column_count
                ,       CASE    WHEN co.system_type_id IN (165,167,173,175,231,239)
                                AND  co.max_length > 32 and co.max_length <=8000
                                THEN COUNT(co.column_id)
                        END                                                 AS long_string_column_count
                FROM    sys.schemas AS sm
                JOIN    sys.tables  AS tb   on sm.[schema_id] = tb.[schema_id]
                JOIN    sys.columns AS co   ON tb.[object_id] = co.[object_id]
                           WHERE tb.name = @TABLE_NAME AND sm.name = @SCHEMA_NAME
                GROUP BY sm.name
                ,        tb.name
                ,        co.system_type_id
                ,        co.max_length            ) a
GROUP BY schema_name
,        table_name
)
, size AS
(
SELECT  schema_name
,       table_name
,       75497472                                            AS table_overhead

,       column_count*1048576*8                              AS column_size
,       short_string_column_count*1048576*32                       AS short_string_size,       (long_string_column_count*16777216) AS long_string_size
FROM    base
UNION
SELECT CASE WHEN COUNT(*) = 0 THEN 'EMPTY' END as schema_name
         ,CASE WHEN COUNT(*) = 0 THEN 'EMPTY' END as table_name
         ,CASE WHEN COUNT(*) = 0 THEN 0 END as table_overhead
         ,CASE WHEN COUNT(*) = 0 THEN 0 END as column_size
         ,CASE WHEN COUNT(*) = 0 THEN 0 END as short_string_size

,CASE WHEN COUNT(*) = 0 THEN 0 END as long_string_size
FROM   base
)
, load_multiplier as
(
SELECT  CASE
          WHEN FLOOR(8 * (CAST (CAST(REPLACE(REPLACE(@DWU,'DW',''),'c','') AS INT) AS FLOAT)/6000)) > 0
            AND CHARINDEX(@DWU,'c')=0
          THEN FLOOR(8 * (CAST (CAST(REPLACE(REPLACE(@DWU,'DW',''),'c','') AS INT) AS FLOAT)/6000))
          ELSE 1
        END AS multiplication_factor
)
       SELECT  r1.DWU
       , schema_name
       , table_name
       , rc.resource_class as closest_rc_in_increasing_order
       , max_queries_at_this_rc = CASE
             WHEN (r1.max_slots / r1.slots_used > r1.max_queries)
                  THEN r1.max_queries
             ELSE r1.max_slots / r1.slots_used
                  END
       , r1.max_slots as max_concurrency_slots
       , r1.slots_used as required_slots_for_the_rc
       , r1.tgt_mem_grant_MB  as rc_mem_grant_MB
       , CAST((table_overhead*1.0+column_size+short_string_size+long_string_size)*multiplication_factor/1048576    AS DECIMAL(18,2)) AS est_mem_grant_required_for_cci_operation_MB
       FROM    size
       , load_multiplier
       , #ref r1, names  rc
       WHERE r1.rc_id=rc.rc_id
                     AND CAST((table_overhead*1.0+column_size+short_string_size+long_string_size)*multiplication_factor/1048576    AS DECIMAL(18,2)) < r1.tgt_mem_grant_MB
       ORDER BY ABS(CAST((table_overhead*1.0+column_size+short_string_size+long_string_size)*multiplication_factor/1048576    AS DECIMAL(18,2)) - r1.tgt_mem_grant_MB)
GO

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

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