Azure Synapse Analytics'de kaynak sınıfları ile iş yükü yönetimi

Synapse için bellek ve eşzamanlılığı yönetmek için kaynak sınıflarını kullanma kılavuzu SQL havuz sorgularını Azure Synapse.

Kaynak sınıfları nedir?

Bir sorgunun performans kapasitesi, kullanıcının kaynak sınıfı tarafından belirlenir. Kaynak sınıfları, Synapse SQL havuzunda sorgu yürütme için işlem kaynaklarını ve eşzamanlılığı yöneten önceden belirlenen kaynak sınırlarıdır. Kaynak sınıfları, eşzamanlı olarak çalıştırılan sorgu sayısına ve her bir sorguya atanan işlem kaynakları üzerinde sınırlar ayarerek sorgularınız için kaynakları yapılandırmanıza yardımcı olabilir. Bellek ve eşzamanlılık arasında bir fark vardır.

  • Daha küçük kaynak sınıfları sorgu başına en fazla belleği azaltır, ancak eşzamanlılığı azaltır.
  • Daha büyük kaynak sınıfları sorgu başına en fazla belleği artırsa da eşzamanlılığı azaltır.

İki tür kaynak sınıfı vardır:

  • Sabit bir veri kümesi boyutu üzerinde artan eşzamanlılık için uygun olan statik kaynak sınıfları.
  • Boyutu artan ve hizmet düzeyi artırıldıklarında performansın artması gereken veri kümeleri için çok uygun olan dinamik kaynak sınıfları.

Kaynak sınıfları, kaynak tüketimini ölçmek için eşzamanlılık yuvalarını kullanır. Eşzamanlılık yuvaları bu makalenin devamlarında açıklanmıştır.

Statik kaynak sınıfları

Statik kaynak sınıfları, veri ambarı birimleriyle ölçülen geçerli performans düzeyine bakılmaksızın aynı miktarda bellek ayırır. Sorgular performans düzeyinden bağımsız olarak aynı bellek ayırmasını elde eder ve veri ambarının ölçeğini genişletme, kaynak sınıfı içinde daha fazla sorgunun çalışmasına olanak sağlar. Veri hacmi biliniyorsa ve sabitse statik kaynak sınıfları idealdir.

Statik kaynak sınıfları şu önceden tanımlanmış veritabanı rolleriyle uygulanır:

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

Dinamik kaynak sınıfları

Dinamik Kaynak Sınıfları, geçerli hizmet düzeyine bağlı olarak değişken miktarda bellek ayırır. Statik kaynak sınıfları daha yüksek eşzamanlılık ve statik veri birimleri için yararlı olsa da, dinamik kaynak sınıfları artan veya değişken miktarda veri için daha uygun olur. Ölçeği daha büyük bir hizmet düzeyine çıkararak sorgularınız otomatik olarak daha fazla bellek elde eder.

Dinamik kaynak sınıfları şu önceden tanımlanmış veritabanı rolleriyle uygulanır:

  • smallrc
  • mediumrc
  • largerc
  • xlargerc

Her kaynak sınıfı için bellek ayırma aşağıdaki gibidir.

Hizmet Düzeyi 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'yi seçin %5 %10 22% %70
DW1000c to
DW30000c
%3 %10 22% %70

Varsayılan kaynak sınıfı

Varsayılan olarak, her kullanıcı smallrc dinamik kaynak sınıfının bir üyesidir.

Hizmet yöneticisinin kaynak sınıfı smallrc'de sabittir ve değiştirilemez. Hizmet yöneticisi, sağlama işlemi sırasında oluşturulan kullanıcıdır. Bu bağlamda hizmet yöneticisi, yeni bir sunucuyla yeni bir Synapse SQL havuzu oluştururken "Sunucu yöneticisi oturum açma bilgileri" için belirtilen oturum açma bilgileridir.

Not

Active Directory yöneticisi olarak tanımlanan kullanıcılar veya gruplar da hizmet yöneticisidir.

Kaynak sınıfı işlemleri

Kaynak sınıfları, veri yönetimi ve işleme etkinliklerinin performansını geliştirmek için tasarlanmıştır. Karmaşık sorgular, büyük bir kaynak sınıfı altında çalıştırmanın avantajından da yararlanabilir. Örneğin, büyük birleşimler ve sıralamalar için sorgu performansı, kaynak sınıfı sorgunun bellekte yürütülebilir olacak kadar büyük olduğunda geliştirebilir.

Kaynak sınıfları tarafından yönetilen işlemler

Bu işlemler kaynak sınıfları tarafından yönetilir:

  • INSERT-SELECT, UPDATE, DELETE
  • SELECT (kullanıcı tablolarını sorgularken)
  • ALTER INDEX - YENIDEN OLUŞTURMA VEYA YENIDEN DÜZENLEME
  • ALTER TABLE REBUILD
  • CREATE INDEX
  • KÜMELENMIŞ COLUMNSTORE DIZINI OLUŞTURMA
  • CREATE TABLE AS SELECT (CTAS)
  • Veri yükleme
  • Veri Taşıma Hizmeti (DMS) tarafından gerçekleştirilen veri taşıma işlemleri

Not

Dinamik yönetim görünümlerine (DMV) veya diğer sistem görünümlerine ilişkin SELECT deyimleri, eşzamanlılık sınırlarının hiçbirine tabi değildir. Üzerinde yürütülen sorgu sayısından bağımsız olarak sistemi izleyebilirsiniz.

İşlemler kaynak sınıfları tarafından yönetilmiyor

Kullanıcı daha büyük bir kaynak sınıfının üyesi olsa bile bazı sorgular her zaman smallrc kaynak sınıfında çalıştır. Bu muaf sorgular eşzamanlılık sınırına sayılmaz. Örneğin, eşzamanlılık sınırı 16 ise, birçok kullanıcı kullanılabilir eşzamanlılık yuvalarını etkilemeden sistem görünümlerinden seçim olabilir.

Aşağıdaki deyimler kaynak sınıflarından muaftır ve her zaman smallrc içinde çalıştırabilirsiniz:

  • CREATE veya DROP TABLE
  • ALTER TABLE ... SWITCH, SPLIT veya MERGE PARTITION
  • ALTER INDEX DISABLE
  • DROP INDEX
  • İSTATISTIK OLUŞTURMA, GÜNCELLEŞTIRME veya BıRAKMA
  • TRUNCATE TABLE
  • ALTER AUTHORIZATION
  • CREATE LOGIN
  • CREATE, ALTER veya DROP USER
  • CREATE, ALTER veya DROP PROCEDURE
  • CREATE veya DROP VIEW
  • DEĞER EKLE
  • Sistem görünümlerinden ve DMV'lerden SEÇIM
  • EXPLAIN
  • DBCC

Eşzamanlılık yuvaları

Eşzamanlılık yuvaları, sorgu yürütme için kullanılabilir kaynakları izlemenin kullanışlı bir yoludur. Bunlar, yemek sınırlı olduğundan bir müzikte yer rezervasyonu yapmak için satın aldığınız biletlere benzer. Veri ambarı başına toplam eşzamanlılık yuvası sayısı hizmet düzeyine göre belirlenir. Bir sorgunun yürütülmeden önce yeterli eşzamanlılık yuvasına sahip olması gerekir. Sorgu tamamlandığında eşzamanlılık yuvalarını serbest bıraktır.

  • 10 eşzamanlılık yuvasıyla çalışan bir sorgu, 2 eşzamanlılık yuvasıyla çalışan bir sorgudan 5 kat daha fazla işlem kaynağına erişebilirsiniz.
  • Her sorgu 10 eşzamanlılık yuvası gerektiriyorsa ve 40 eşzamanlılık yuvası varsa, eşzamanlı olarak yalnızca 4 sorgu çalıştırabilirsiniz.

Yalnızca kaynak tarafından yönetilen sorgular eşzamanlılık yuvalarını tüketir. Sistem sorguları ve bazı önemsiz sorgular yuva tüketmez. Tüketilen eşzamanlılık yuvalarının tam sayısı sorgunun kaynak sınıfı tarafından belirlenir.

Kaynak sınıflarını görüntüleme

Kaynak sınıfları önceden tanımlanmış veritabanı rolleri olarak uygulanır. İki tür kaynak sınıfı vardır: dinamik ve statik. Kaynak sınıflarının listesini görüntülemek için aşağıdaki sorguyu kullanın:

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

Kullanıcının kaynak sınıfını değiştirme

Kaynak sınıfları, veritabanı rollerine kullanıcı atanarak uygulanır. Kullanıcı bir sorgu çalıştırsa, sorgu kullanıcının kaynak sınıfıyla çalışır. Örneğin, bir kullanıcı staticrc10 veritabanı rolünün bir üyesi ise, sorguları küçük miktarlarda bellekle çalıştırmaktadır. Veritabanı kullanıcısı xlargerc veya staticrc80 veritabanı rollerinin üyesi ise, sorguları büyük miktarlarda bellekle çalıştırıldı.

Bir kullanıcının kaynak sınıfını artırmak için sp_addrolemember kullanarak büyük bir kaynak sınıfının veritabanı rolüne ekleyin. Aşağıdaki kod, largerc veritabanı rolüne bir kullanıcı ekler. Her istek, sistem belleğinin %22'sinde yer alır.

EXEC sp_addrolemember 'largerc', 'loaduser';

Kaynak sınıfını azaltmak için sp_droprolemember. 'loaduser' bir üye veya başka bir kaynak sınıfı yoksa, %3 bellek izni ile varsayılan smallrc kaynak sınıfına gider.

EXEC sp_droprolemember 'largerc', 'loaduser';

Kaynak sınıfı önceliği

Kullanıcılar birden çok kaynak sınıfına üye olabilir. Bir kullanıcı birden fazla kaynak sınıfına ait olduğunda:

  • Dinamik kaynak sınıfları statik kaynak sınıflarına göre önceliklidir. Örneğin, bir kullanıcı hem mediumrc(dynamic) hem de staticrc80 (statik) üyesi ise, sorgular mediumrc ile çalıştırıldı.
  • Daha büyük kaynak sınıfları, daha küçük kaynak sınıflarına göre önceliklidir. Örneğin, bir kullanıcı mediumrc ve largerc üyesi ise, sorgular largerc ile çalıştır. Benzer şekilde, bir kullanıcı hem staticrc20 hem de statirc80'in üyesi ise sorgular staticrc80 kaynak ayırmaları ile çalıştırıldı.

Öneriler

Not

İş yükünüz üzerinde daha fazla denetim veöngörülebilirperformans için iş yükü yönetimi özelliklerini (iş yükü yalıtımı, sınıflandırma ve önem) değerlendirin.

Belirli bir sorgu veya yükleme işlemi türünü çalıştırmaya ayrılmış bir kullanıcı oluşturmanizi öneririz. Kaynak sınıfını sık sık değiştirmek yerine bu kullanıcıya kalıcı bir kaynak sınıfı verme. Statik kaynak sınıfları iş yükü üzerinde daha fazla denetime sahip olabilir, bu nedenle dinamik kaynak sınıflarını dikkate alamayıp statik kaynak sınıflarını kullanmanızı öneririz.

Yük kullanıcıları için kaynak sınıfları

CREATE TABLE varsayılan olarak kümelenmiş columnstore dizinlerini kullanır. Verileri columnstore dizinine sıkıştırmak bellek kullanımı yoğun bir işlemdir ve bellek baskısı dizin kalitesini düşürebilirsiniz. Bellek baskısı, verileri yüklerken daha yüksek bir kaynak sınıfına ihtiyaçlara neden olabilir. Yüklerin yeterli belleğe sahip olduğundan emin olmak için, yükleri çalıştırmaya atanmış bir kullanıcı oluşturabilir ve bu kullanıcıyı daha yüksek bir kaynak sınıfına at uygun şekilde atebilirsiniz.

Yükleri verimli bir şekilde işlemesi için gereken bellek, yüklenen tablonun doğasına ve veri boyutuna bağlıdır. Bellek gereksinimleri hakkında daha fazla bilgi için bkz. Rowgroup kalitesini en üst düzeye çıkarma.

Bellek gereksinimini belirlediktan sonra, yük kullanıcısını statik veya dinamik bir kaynak sınıfına atamayı seçin.

  • Tablo belleği gereksinimleri belirli bir aralıkta olduğunda statik kaynak sınıfı kullanın. Yükler uygun bellekle çalıştır. Veri ambarlarını ölçeklendirin, yüklerin daha fazla belleğe ihtiyacı olmaz. Statik kaynak sınıfı kullanılarak bellek ayırmaları sabit kalır. Bu tutarlılık bellek tasarrufu sağlar ve eşzamanlı olarak daha fazla sorgu çalıştırmaya olanak sağlar. Yeni çözümlerin ilk olarak statik kaynak sınıflarını kullanmalarını öneririz çünkü bunlar daha fazla denetim sağlar.
  • Tablo belleği gereksinimleri büyük ölçüde farklılık gösterirken dinamik bir kaynak sınıfı kullanın. Yükler, geçerli DWU veya cDWU düzeyinden daha fazla bellek gerektirir. Veri ambarlarını ölçeklendirmek, yükleme işlemlerine daha fazla bellek ekler ve bu da yüklerin daha hızlı bir şekilde performansa olanak sağlar.

Sorgular için kaynak sınıfları

Bazı sorgular yoğun işlem gücü kullanımına ve bazıları yoğun olmayan sorgulara neden olur.

  • Sorgular karmaşık olduğunda ancak yüksek eşzamanlılık gerektir etmeyen dinamik bir kaynak sınıfı seçin. Örneğin, günlük veya haftalık raporlar oluşturmak, kaynaklara yönelik ara sıra ihtiyaçlara neden olur. Raporlar büyük miktarlarda veri işlemektedir, veri ambarını ölçeklendirmek kullanıcının mevcut kaynak sınıfına daha fazla bellek sağlar.
  • Gün boyunca kaynak beklentileri farklı olduğunda statik bir kaynak sınıfı seçin. Örneğin, veri ambarı birçok kişi tarafından sorgulanan statik kaynak sınıfı iyi çalışır. Veri ambarı ölçeklendir edilirken kullanıcıya ayrılan bellek miktarı değişmez. Sonuç olarak sistemde paralel olarak daha fazla sorgu yürütülmektedir.

Doğru bellek verilmesi sorgulanan veri miktarı, tablo şemalarının doğası ve çeşitli birleştirmeler, seçme ve grup koşulları gibi birçok faktöre bağlıdır. Genel olarak, daha fazla bellek, sorguların daha hızlı tamamlanmasına olanak sağlar, ancak genel eşzamanlılığı azaltır. Eşzamanlılık bir sorun yoksa, fazla alan bellek aktarım hızına zarar vermez.

Performansı ayarlamak için farklı kaynak sınıfları kullanın. Sonraki bölümde, en iyi kaynak sınıfını anlamanıza yardımcı olacak bir saklı yordam vemektedir.

En iyi kaynak sınıfını bulmak için örnek kod

Belirli bir SLO'da kaynak sınıfı başına eşzamanlılık ve bellek iznini ve belirli bir kaynak sınıfında bölümlenmiş olmayan CCI tablosunda yoğun bellek kullanımına sahip CCI işlemleri için en iyi kaynak sınıfını ortaya koyan aşağıdaki belirtilen saklı yordamı kullanabilirsiniz:

Bu saklı yordamın amacı şu şekildedir:

  1. Belirli bir SLO'da kaynak sınıfı başına eşzamanlılık ve bellek iznini görmek için. Kullanıcının bu örnekte gösterildiği gibi hem şema hem de tablo adı için NULL sağlaması gerekir.
  2. Belirli bir kaynak sınıfında bölümlenmiş olmayan CCI tablosunda bellek kullanımı yoğun CCI işlemlerine (yükleme, tablo kopyalama, dizini yeniden oluşturma vb.) yönelik en iyi kaynak sınıfını görmek için. Saklı yordam, gerekli bellek iznini bulmak için tablo şemasını kullanır.

Bağımlılıklar & Kısıtlamaları

  • Bu saklı yordam, bölümlenmiş bir cci tablosu için bellek gereksinimini hesaplamak üzere tasarlanmamış.
  • Bu saklı yordam, CTAS/INSERT-SELECT'in SELECT bölümü için bellek gereksinimlerini dikkate almaz ve bunun bir SELECT olduğunu varsaymaktadır.
  • Bu saklı yordam, bu saklı yordamın oluşturulmuş olduğu oturumda kullanılabilen bir geçici tablo kullanır.
  • Bu saklı yordam, geçerli tekliflere (örneğin, donanım yapılandırması, DMS config) bağlıdır ve bu değişikliklerden herhangi biri doğru şekilde çalışmaz.
  • Bu saklı yordam, mevcut eşzamanlılık sınırı tekliflerine bağlıdır ve bu değişiklikler bu saklı yordam doğru şekilde çalışmaz.
  • Bu saklı yordam mevcut kaynak sınıfı tekliflerine bağlıdır ve bu değişiklikler bu saklı yordam doğru şekilde çalışmaz.

Not

Saklı yordamı belirtilen parametrelerle yürüttükten sonra çıkış almıyorsanız, iki durum olabilir.

  1. DW parametresi geçersiz bir SLO değeri içeriyor
  2. Veya, tablodaki CCı işlemi için eşleşen bir kaynak sınıfı yok.

Örneğin, DW100c adresinde en yüksek bellek verme 1 GB 'tır ve tablo şeması, 1 GB gereksinimini ortadan yatabilecek kadar genişse.

Kullanım örneği

Söz dizimi:
EXEC dbo.prc_workload_management_by_DWU @DWU VARCHAR(7), @SCHEMA_NAME VARCHAR(128), @TABLE_NAME VARCHAR(128)

  1. @DWU: DW DB 'den geçerli DWU 'yi ayıklamak için NULL bir parametre sağlayın ya da ' DW100c ' biçiminde desteklenen DWU 'yi sağlayın
  2. @SCHEMA_NAME: Tablo için bir şema adı sağlayın
  3. @TABLE_NAME: İlgilendiğiniz bir tablo adı girin

Bu saklı proc yürütülen örnekler:

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;  

Aşağıdaki ifade, önceki örneklerde kullanılan Table1 oluşturur. CREATE TABLE Table1 (a int, b varchar(50), c decimal (18,10), d char(10), e varbinary(15), f float, g datetime, h date);

Saklı yordam tanımı

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

Sonraki adımlar

Veritabanı kullanıcılarını ve güvenliğini yönetme hakkında daha fazla bilgi için bkz. Synapse SQL 'de veritabanını güvenli hale getirme. Daha büyük kaynak sınıflarının kümelenmiş columnstore dizini kalitesini nasıl iyileştirebilecek hakkında daha fazla bilgi için bkz. columnstore sıkıştırması Için bellek iyileştirmeleri.