Számítási feladatok kezelése erőforrásosztályokkal az Azure Synapse Analyticsben

Útmutató az azure Synapse-beli Synapse SQL-készlet lekérdezéseinek memóriájának és egyidejűségének kezeléséhez erőforrásosztályok használatával.

Mik azok az erőforrásosztályok?

A lekérdezések teljesítménykapacitását a felhasználó erőforrásosztálya határozza meg. Az erőforrásosztályok előre meghatározott erőforráskorlátok a Synapse SQL-készletben, amelyek a számítási erőforrásokat és a lekérdezések végrehajtásának egyidejűségét szabályozzák. Az erőforrásosztályok segíthetnek az erőforrások lekérdezésekhez való konfigurálásában azáltal, hogy korlátozza az egyidejűleg futó lekérdezések számát és az egyes lekérdezésekhez rendelt számítási erőforrásokat. Van egy kompromisszum a memória és az egyidejűség között.

  • A kisebb erőforrásosztályok csökkentik a lekérdezésenkénti maximális memóriát, de növelik az egyidejűséget.
  • A nagyobb erőforrásosztályok növelik a lekérdezésenkénti maximális memóriát, de csökkentik az egyidejűséget.

Az erőforrásosztályok kétféleképpen használhatók:

  • Statikus erőforrásosztályok, amelyek kiválóan alkalmasak a rögzített adathalmazméretek nagyobb egyidejűségére.
  • Dinamikus erőforrásosztályok, amelyek megfelelőek a növekvő méretű adathalmazokhoz, és nagyobb teljesítményt igényelnek a szolgáltatási szint felskálázása során.

Az erőforrásosztályok egyidejűségi pontok használatával mérik az erőforrás-felhasználást. Az egyidejűségi pontokat a cikk későbbi részében ismertetjük.

Statikus erőforrásosztályok

A statikus erőforrásosztályok az aktuális teljesítményszinttől függetlenül ugyanazt a memóriamennyiséget foglalják le, amelyet az adattárházegységekben mérnek. Mivel a lekérdezések a teljesítményszinttől függetlenül ugyanazt a memóriafoglalást kapják, az adattárház horizontális felskálázásával több lekérdezés futtatható egy erőforrásosztályon belül. A statikus erőforrásosztályok akkor ideálisak, ha az adatkötet ismert és állandó.

A statikus erőforrásosztályok az alábbi előre definiált adatbázis-szerepkörökkel vannak implementálva:

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

Dinamikus erőforrásosztályok

A dinamikus erőforrásosztályok az aktuális szolgáltatási szinttől függően változó mennyiségű memóriát foglalnak le. Bár a statikus erőforrásosztályok előnyösek a magasabb egyidejűség és a statikus adatmennyiségek esetében, a dinamikus erőforrásosztályok jobban megfelelnek a növekvő vagy változó adatmennyiségnek. Ha nagyobb szolgáltatási szintre méretez fel, a lekérdezések automatikusan több memóriát kapnak.

A dinamikus erőforrásosztályok az alábbi előre definiált adatbázis-szerepkörökkel vannak implementálva:

  • smallrc
  • mediumrc
  • largerc
  • xlargerc

Az egyes erőforrásosztályok memóriafoglalása a következő.

Szolgáltatásszint 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 lehetőséget 5% 10% 22% 70%
DW1000c a
DW30000c
3% 10% 22% 70%

Alapértelmezett erőforrásosztály

Alapértelmezés szerint minden felhasználó tagja a smallrc dinamikus erőforrásosztálynak.

A szolgáltatásadminisztrátor erőforrásosztálya a smallrc helyen van javítva, és nem módosítható. A szolgáltatásadminisztrátor a kiépítési folyamat során létrehozott felhasználó. Ebben a kontextusban a szolgáltatásadminisztrátor a "Kiszolgálói rendszergazdai bejelentkezés" beállításhoz megadott bejelentkezés, amikor új Synapse SQL-készletet hoz létre egy új kiszolgálóval.

Megjegyzés:

Az Active Directory-rendszergazdaként definiált felhasználók és csoportok szintén szolgáltatás-rendszergazdák.

Erőforrásosztály-műveletek

Az erőforrásosztályok célja az adatkezelési és -kezelési tevékenységek teljesítményének javítása. Az összetett lekérdezések nagy erőforrásosztályban is futtathatók. Például a nagy illesztések és rendezések lekérdezési teljesítménye javulhat, ha az erőforrásosztály elég nagy ahhoz, hogy lehetővé tegye a lekérdezés végrehajtását a memóriában.

Erőforrásosztályok által szabályozott műveletek

Ezeket a műveleteket erőforrásosztályok szabályozzák:

  • IN Standard kiadás RT-Standard kiadás LECT, UPDATE, DELETE
  • Standard kiadás LECT (felhasználói táblák lekérdezésekor)
  • ALTER INDEX – ÚJRAÉPÍTÉS VAGY ÁTRENDEZÉS
  • A TÁBLA ÚJRAÉPÍTÉSÉNEK MÓDOSÍTÁSA
  • CREATE INDEX
  • FÜRTÖZÖTT OSZLOPCENTRIKUS INDEX LÉTREHOZÁSA
  • TÁBLA LÉTREHOZÁSA STANDARD KIADÁS LECT (CTAS)
  • Az adatok betöltése
  • Az adatáthelyezési szolgáltatás (DMS) által végzett adatátviteli műveletek

Megjegyzés:

Standard kiadás Dinamikus felügyeleti nézetekre (DMV-k) vagy más rendszernézetekre vonatkozóLECT-utasításokra nem vonatkoznak az egyidejűségi korlátok. A rendszeren futtatott lekérdezések számától függetlenül figyelheti a rendszert.

Erőforrásosztályok által nem szabályozott műveletek

Egyes lekérdezések mindig a smallrc erőforrásosztályban futnak, annak ellenére, hogy a felhasználó egy nagyobb erőforrásosztály tagja. Ezek a kivétel nélküli lekérdezések nem számítanak bele az egyidejűségi korlátba. Ha például az egyidejűségi korlát 16, akkor sok felhasználó a rendelkezésre álló egyidejűségi pontok befolyásolása nélkül választhat a rendszernézetekből.

A következő utasítások mentesülnek az erőforrásosztályok alól, és mindig a smallrc-ben futnak:

  • CREATE vagy DROP TABLE
  • ALTER TABLE ... PARTÍCIÓ VÁLTÁSA, FELOSZTÁSA VAGY EGYESÍTÉSE
  • AZ ALTER INDEX LETILTÁSA
  • DROP INDEX
  • STATISZTIKÁK LÉTREHOZÁSA, FRISSÍTÉSE VAGY ELVETÉSE
  • TRUNCATE TABLE
  • ALTER AUTHORIZATION
  • CREATE LOGIN
  • CREATE, ALTER vagy DROP U Standard kiadás R
  • LÉTREHOZÁSI, MÓDOSÍTÁSI VAGY ELVETÉSI ELJÁRÁS
  • LÉTREHOZÁS VAGY DROP NÉZET
  • IN STANDARD KIADÁS RT ÉRTÉKEK
  • Standard kiadás LECT rendszernézetekből és DMV-kből
  • EXPLAIN
  • DBCC

Egyidejűségi pontok

Az egyidejűségi pontok kényelmesen követik a lekérdezés végrehajtásához rendelkezésre álló erőforrásokat. Ezek olyanok, mint a jegyek, amelyeket a koncertek foglalásához vásárol, mert az ülőhelyek korlátozottak. Az adattárházonkénti egyidejűségi pontok teljes számát a szolgáltatási szint határozza meg. Mielőtt egy lekérdezés elkezdené a végrehajtást, elegendő egyidejűségi helyet kell lefoglalnia. Amikor egy lekérdezés befejeződik, felszabadítja az egyidejűségi pontjait.

  • A 10 egyidejűséggel rendelkező lekérdezések ötször több számítási erőforráshoz férhetnek hozzá, mint a 2 egyidejűséggel rendelkező lekérdezéshez.
  • Ha minden lekérdezéshez 10 egyidejűségi pont szükséges, és 40 egyidejűségi pont van, akkor egyszerre csak 4 lekérdezés futtatható.

Csak az erőforrás által szabályozott lekérdezések használnak egyidejűségi pontokat. A rendszer-lekérdezések és néhány apró lekérdezés nem használ fel tárolóhelyet. A felhasznált egyidejűségi pontok pontos számát a lekérdezés erőforrásosztálya határozza meg.

Az erőforrásosztályok megtekintése

Az erőforrásosztályok előre definiált adatbázis-szerepkörökként vannak implementálva. Az erőforrásosztályok két típusa létezik: dinamikus és statikus. Az erőforrásosztályok listájának megtekintéséhez használja a következő lekérdezést:

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

Felhasználó erőforrásosztályának módosítása

Az erőforrásosztályok úgy implementálódnak, hogy felhasználókat rendelnek adatbázis-szerepkörökhöz. Amikor egy felhasználó lekérdezést futtat, a lekérdezés a felhasználó erőforrásosztályával fut. Ha például egy felhasználó tagja a staticrc10 adatbázisszerepkörnek, a lekérdezések kis mennyiségű memóriával futnak. Ha egy adatbázis-felhasználó tagja az xlargerc vagy staticrc80 adatbázis-szerepköröknek, a lekérdezések nagy mennyiségű memóriával futnak.

A felhasználó erőforrásosztályának növeléséhez a sp_addrolemember segítségével vegye fel a felhasználót egy nagy erőforrásosztály adatbázisszerepkörére. Az alábbi kód hozzáad egy felhasználót a nagyobb méretű adatbázis szerepkörhöz. Minden kérés a rendszermemória 22%-át kapja meg.

EXEC sp_addrolemember 'largerc', 'loaduser';

Az erőforrásosztály csökkentéséhez használja a sp_droprolemember. Ha a "loaduser" nem tag vagy más erőforrásosztály, akkor az alapértelmezett smallrc erőforrásosztályba kerül, 3%-os memóriakiadással.

EXEC sp_droprolemember 'largerc', 'loaduser';

Erőforrásosztályok elsőbbsége

A felhasználók több erőforrásosztály tagjai lehetnek. Ha egy felhasználó egynél több erőforrásosztályhoz tartozik:

  • A dinamikus erőforrásosztályok elsőbbséget élveznek a statikus erőforrásosztályokkal szemben. Ha például egy felhasználó a mediumrc(dynamic) és a staticrc80 (statikus) tagja is, a lekérdezések a mediumrc használatával futnak.
  • A nagyobb erőforrásosztályok elsőbbséget élveznek a kisebb erőforrásosztályokkal szemben. Ha például egy felhasználó a mediumrc és a largerc tagja, a lekérdezések a largerc használatával futnak. Hasonlóképpen, ha egy felhasználó a staticrc20 és a statirc80 tagja is, a lekérdezések staticrc80 erőforrás-foglalásokkal futnak.

Javaslatok

Megjegyzés:

Fontolja meg a számítási feladatok kezelési képességeinek (számítási feladatok elkülönítése, besorolása és fontossága) kihasználását a számítási feladatok és a kiszámítható teljesítmény hatékonyabb szabályozása érdekében.

Javasoljuk, hogy hozzon létre egy olyan felhasználót, aki egy adott típusú lekérdezési vagy betöltési művelet futtatására van dedikáltan. Adjon a felhasználónak állandó erőforrásosztályt ahelyett, hogy gyakran módosítaná az erőforrásosztályt. A statikus erőforrásosztályok nagyobb átfogó felügyeletet biztosít a számítási feladathoz, ezért javasoljuk, hogy a dinamikus erőforrásosztályok mérlegelése előtt használjon statikus erőforrásosztályokat.

Erőforrásosztályok betöltési felhasználók számára

CREATE TABLE alapértelmezés szerint fürtözött oszlopcentrikus indexeket használ. Az adatok oszlopcentrikus indexbe való tömörítése memóriaigényes művelet, és a memóriaterhelés csökkentheti az index minőségét. A memóriaterhelés miatt az adatok betöltésekor magasabb erőforrásosztályra lehet szükség. Annak érdekében, hogy a terhelések elegendő memóriával rendelkezzenek, létrehozhat egy terhelések futtatására kijelölt felhasználót, és hozzárendelheti a felhasználót egy magasabb erőforrásosztályhoz.

A terhelés hatékony feldolgozásához szükséges memória a betöltött tábla jellegétől és az adatmérettől függ. A memóriakövetelményekkel kapcsolatos további információkért tekintse meg a sorcsoport minőségének maximalizálása című témakört.

A memóriakövetelmény meghatározása után válassza ki, hogy a terhelési felhasználót statikus vagy dinamikus erőforrásosztályhoz kívánja-e rendelni.

  • Statikus erőforrásosztályt használjon, ha a táblamemória követelményei egy adott tartományba esnek. A terhelések megfelelő memóriával futnak. Az adattárház méretezésekor a terheléseknek nincs szükségük több memóriára. Statikus erőforrásosztály használatával a memóriafoglalások állandóak maradnak. Ez a konzisztencia megőrzi a memóriát, és több lekérdezés egyidejű futtatását teszi lehetővé. Javasoljuk, hogy az új megoldások először a statikus erőforrásosztályokat használják, mivel ezek nagyobb felügyeletet biztosítanak.
  • Dinamikus erőforrásosztályt használjon, ha a táblamemória követelményei nagy mértékben eltérnek. A terhelések több memóriát igényelhetnek, mint a jelenlegi DWU vagy cDWU szint. Az adattárház skálázása több memóriát ad a betöltési műveletekhez, ami lehetővé teszi a terhelések gyorsabb végrehajtását.

Erőforrásosztályok lekérdezésekhez

Egyes lekérdezések nagy számítási igényűek, mások pedig nem.

  • Akkor válasszon dinamikus erőforrásosztályt, ha a lekérdezések összetettek, de nem igényelnek magas egyidejűséget. Például napi vagy heti jelentések létrehozása időnként szükség van erőforrásokra. Ha a jelentések nagy mennyiségű adatot dolgoznak fel, az adattárház skálázása több memóriát biztosít a felhasználó meglévő erőforrásosztályának.
  • Akkor válasszon statikus erőforrásosztályt, ha az erőforrásokkal kapcsolatos elvárások a nap folyamán változnak. Egy statikus erőforrásosztály például akkor működik jól, ha az adattárházat sokan kérdezik le. Az adattárház skálázása során a felhasználó számára lefoglalt memória mennyisége nem változik. Következésképpen több lekérdezés is végrehajtható párhuzamosan a rendszeren.

A megfelelő memóriahasználat számos tényezőtől függ, például a lekérdezett adatok mennyiségétől, a táblázat sémáinak jellegétől, valamint a különböző illesztésektől, kiválasztási és csoportosítási predikátumoktól. Általánosságban elmondható, hogy a több memória kiosztása lehetővé teszi a lekérdezések gyorsabb végrehajtását, de csökkenti az általános egyidejűséget. Ha az egyidejűség nem jelent problémát, a memória túlosztása nem rontja az átviteli sebességet.

A teljesítmény finomhangolásához használjon különböző erőforrásosztályokat. A következő szakasz egy tárolt eljárást biztosít, amely segít a legjobb erőforrásosztály megállapításában.

Példakód a legjobb erőforrásosztály megtalálásához

Az alábbi tárolt eljárással megállapíthatja, hogy egy adott SLO-n az erőforrásosztályonkénti egyidejűség és memóriakiadás, valamint a memóriaigényes CCI-műveletekhez a legjobb erőforrásosztály egy adott erőforrásosztály nem particionált CCI-tábláján:

A tárolt eljárás célja a következő:

  1. Az egyidejűség és a memória megadásának megtekintése erőforrásosztályonként egy adott SLO-ban. A felhasználónak null értéket kell megadnia a sémához és a táblanévhez is, ahogyan az ebben a példában látható.
  2. A memóriaigényes CCI-műveletek (terhelés, másolási táblázat, újraépítési index stb.) legjobb erőforrásosztályának megtekintése egy adott erőforrásosztály nem particionált CCI-tábláján. A tárolt proc táblasémával állapítja meg a szükséges memóriahasználatot.

Függőségek > korlátozások

  • Ez a tárolt eljárás nem a particionált cci-táblák memóriaigényének kiszámítására szolgál.
  • Ez a tárolt eljárás nem veszi figyelembe a CTAS/IN Standard kiadás RT-Standard kiadás LECT Standard kiadás LECT részét, és feltételezi, hogy ez egy Standard kiadás LECT.
  • Ez a tárolt eljárás egy ideiglenes táblát használ, amely abban a munkamenetben érhető el, ahol a tárolt eljárás létrejött.
  • Ez a tárolt eljárás az aktuális ajánlatoktól (például hardverkonfigurációtól, DMS-konfigurációtól) függ, és ha ezek bármelyike megváltozik, a tárolt proc nem fog megfelelően működni.
  • Ez a tárolt eljárás a meglévő egyidejűségi korlátajánlatoktól függ, és ha ezek megváltoznak, akkor ez a tárolt eljárás nem fog megfelelően működni.
  • Ez a tárolt eljárás a meglévő erőforrásosztály-ajánlatoktól függ, és ha ezek módosulnak, akkor ez a tárolt eljárás nem fog megfelelően működni.

Megjegyzés:

Ha a megadott paraméterekkel rendelkező tárolt eljárás végrehajtása után nem kap kimenetet, akkor két eset lehet.

  1. Bármelyik DW paraméter érvénytelen SLO-értéket tartalmaz
  2. Vagy a táblában nincs egyező erőforrásosztály a CCI-művelethez.

A DW100c esetében például a legmagasabb rendelkezésre álló memóriahozzáférés 1 GB, és ha a táblázatséma elég széles ahhoz, hogy átlépje az 1 GB-os követelményt.

Használati példa

Szintaxis:
EXEC dbo.prc_workload_management_by_DWU @DWU VARCHAR(7), @SCHEMA_NAME VARCHAR(128), @TABLE_NAME VARCHAR(128)

  1. @DWU: Adjon meg egy NULL paramétert az aktuális DWU kinyeréséhez a DW DB-ből, vagy adjon meg bármilyen támogatott DWU-t "DW100c" formátumban
  2. @SCHEMA_NAME: Adja meg a tábla sémanevét
  3. @TABLE_NAME: Adja meg a kamattáblázat nevét

Példák a tárolt proc végrehajtására:

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;  

Az alábbi utasítás az előző példákban használt 1. táblázatot hozza létre. CREATE TABLE Table1 (a int, b varchar(50), c decimal (18,10), d char(10), e varbinary(15), f float, g datetime, h date);

Tárolt eljárás definíciója

-------------------------------------------------------------------------------
-- 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

További lépések

Az adatbázis-felhasználók és a biztonság kezelésével kapcsolatos további információkért tekintse meg az adatbázis biztonságossá tételét a Synapse SQL-ben. További információ arról, hogy a nagyobb erőforrásosztályok hogyan javíthatják a fürtözött oszlopcentrikus index minőségét: Memóriaoptimalizálás az oszlopcentrikus tömörítéshez.