Azure SQL Yönetilen Örneği bellek içi örneği

Şunlar için geçerlidir:Azure SQL Yönetilen Örneği

Azure SQL Yönetilen Örneği'daki bellek içi teknolojiler uygulamanızın performansını artırmanıza ve veritabanınızın maliyetini azaltmanıza olanak tanır. Azure SQL Yönetilen Örneği'da bellek içi teknolojileri kullanarak çeşitli iş yükleriyle performans iyileştirmeleri elde edebilirsiniz.

Bu makalede bellek içi OLTP kullanımını gösteren iki örnek ve Azure SQL Yönetilen Örneği'da columnstore dizinleri göreceksiniz.

Daha fazla bilgi için bkz.

Bellek içi OLTP için daha basit ama görsel açıdan daha çekici bir performans tanıtımı için bkz:

1. Bellek içi OLTP örnek veritabanını geri yükleme

SQL Server Management Studio'da AdventureWorksLT(SSMS) birkaç T-SQL adımıyla örnek veritabanını geri yükleyebilirsiniz. Veritabanını SQL yönetilen örneğine geri yükleme hakkında daha fazla bilgi için bkz. Hızlı Başlangıç: SSMS ile Azure SQL Yönetilen Örneği için veritabanını geri yükleme.

Ardından bu bölümdeki adımlar, veritabanınızı AdventureWorksLT bellek içi OLTP nesneleriyle nasıl zenginleştirebileceğinizi ve performans avantajlarını nasıl gösterebileceğinizi açıklar.

  1. SSMS'yi açın ve SQL yönetilen örneğine bağlanın.

    Not

    Azure SQL Yönetilen Örneği şirket içi iş istasyonunuzdan veya Azure VM'den Bağlan, genel erişim açılmadan güvenli bir şekilde yapılabilir. Hızlı Başlangıç: Şirket içinden Azure SQL Yönetilen Örneği için noktadan siteye bağlantı yapılandırma veya Hızlı Başlangıç: Azure VM'yi Azure SQL Yönetilen Örneği bağlanacak şekilde yapılandırma konusunu göz önünde bulundurun.

  2. Nesne Gezgini'da yönetilen örneğinize sağ tıklayın ve Yeni Sorgu'yu seçerek yeni bir sorgu penceresi açın.

  3. SQL yönetilen örneğinizde kimlik bilgisi oluşturmak için genel kullanıma açık önceden yapılandırılmış depolama kapsayıcısını ve paylaşılan erişim imza anahtarını kullanan aşağıdaki T-SQL deyimini çalıştırın. Genel kullanıma açık depolamada SAS imzası gerekmez.

    CREATE CREDENTIAL [https://mitutorials.blob.core.windows.net/examples/]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE';
    
  4. Örnek AdventureWorksLT veritabanını geri yüklemek için aşağıdaki deyimi çalıştırın.

    RESTORE DATABASE [AdventureWorksLT] 
    FROM URL = 'https://mitutorials.blob.core.windows.net/examples/AdventureWorksLT2022.bak';
    
  5. Geri yükleme işleminizin durumunu izlemek için aşağıdaki deyimi çalıştırın.

    SELECT session_id as SPID, command, a.text AS Query, start_time, percent_complete
       , dateadd(second,estimated_completion_time/1000, getdate()) as estimated_completion_time
    FROM sys.dm_exec_requests r
    CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) a
    WHERE r.command in ('BACKUP DATABASE','RESTORE DATABASE');
    
  6. Geri yükleme işlemi tamamlandığında veritabanını Nesne Gezgini görüntüleyin AdventureWorksLT. sys.dm_operation_status görünümünü kullanarak veritabanının geri yüklendiğini doğrulayabilirsinizAdventureWorksLT.

Oluşturulan bellek için iyileştirilmiş öğeler hakkında

Tablolar: Örnek, bellek için iyileştirilmiş aşağıdaki tabloları içerir:

  • SalesLT.Product_inmem
  • SalesLT.SalesOrderHeader_inmem
  • SalesLT.SalesOrderDetail_inmem
  • Demo.DemoSalesOrderHeaderSeed
  • Demo.DemoSalesOrderDetailSeed

SSMS'deki Nesne Gezgini yalnızca bellek için iyileştirilmiş tabloları gösterecek şekilde filtreleyebilirsiniz. Tablolar'a sağ tıkladığınızda Filtre Filtresi Ayarlar> Bellek için İyileştirilmiş'e>> gidin. değeri eşittir 1.

Veya katalog görünümlerini sorgulayabilirsiniz, örneğin:

SELECT is_memory_optimized, name, type_desc, durability_desc
    FROM sys.tables
    WHERE is_memory_optimized = 1;

Yerel olarak derlenmiş saklı yordam: Katalog görünümü sorgusu aracılığıyla inceleyebilirsiniz SalesLT.usp_InsertSalesOrder_inmem :

SELECT uses_native_compilation, OBJECT_NAME(object_id), definition
    FROM sys.sql_modules
    WHERE uses_native_compilation = 1;

2. Örnek OLTP iş yükünü çalıştırma

Aşağıdaki iki saklı yordam arasındaki tek fark, ilk yordamın tabloların bellek için iyileştirilmiş sürümlerini, ikinci yordam ise normal disk içi tabloları kullanmasıdır:

  • SalesLT.usp_InsertSalesOrder_inmem
  • SalesLT.usp_InsertSalesOrder_ondisk

Bu bölümde, iki saklı yordamı stresli düzeylerde yürütmek için kullanışlı ostress.exe yardımcı programının nasıl kullanılacağını göreceksiniz. İki stres çalıştırmasının tamamlanmasının ne kadar sürdüğünü karşılaştırabilirsiniz.

RML yardımcı programlarını ve ostress'i yükleme

İdeal olarak, ostress.exe bir Azure sanal makinesinde (VM) çalıştırmayı planlıyorsunuz. SQL yönetilen örneğiniz ile aynı Azure bölgesinde bir Azure VM oluşturabilirsiniz. Ancak Azure SQL yönetilen örneğinize bağlanabildiğiniz sürece ostress.exe yerel iş istasyonunuzda çalıştırabilirsiniz.

VM'de veya seçtiğiniz herhangi bir konakta Yeniden Yürütme biçimlendirme dili (RML) yardımcı programlarını yükleyin. Yardımcı programlar ostress.exe içerir.

Daha fazla bilgi için bkz.

ostress.exe için betik

Bu bölümde, ostress.exe komut satırımıza eklenmiş olan T-SQL betiği görüntülenir. Betik, daha önce yüklediğiniz T-SQL betiği tarafından oluşturulan öğeleri kullanır.

ostress.exe çalıştırdığınızda, aşağıdaki stratejilerin ikisini de kullanarak iş yükünü vurgulayan parametre değerlerini geçirmenizi öneririz:

  • kullanarak -n100çok sayıda eşzamanlı bağlantı çalıştırın.
  • kullanarak her bağlantının yüzlerce kez -r500tekrarlamalarını sağlayın.

Ancak, ve gibi -n10-r50 çok daha küçük değerlerle başlamak ve her şeyin çalıştığından emin olmak isteyebilirsiniz.

Aşağıdaki betik, aşağıdaki bellek için iyileştirilmiş tablolara beş satır öğe içeren bir örnek satış siparişi ekler:

  • SalesLT.SalesOrderHeader_inmem
  • SalesLT.SalesOrderDetail_inmem
DECLARE
    @i int = 0,
    @od SalesLT.SalesOrderDetailType_inmem,
    @SalesOrderID int,
    @DueDate datetime2 = sysdatetime(),
    @CustomerID int = rand() * 8000,
    @BillToAddressID int = rand() * 10000,
    @ShipToAddressID int = rand() * 10000;

INSERT INTO @od
    SELECT OrderQty, ProductID
    FROM Demo.DemoSalesOrderDetailSeed
    WHERE OrderID= cast((rand()*60) as int);

WHILE (@i < 20)
BEGIN;
    EXECUTE SalesLT.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT,
        @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @od;
    SET @i = @i + 1;
END

ostress.exe için önceki T-SQL betiğinin _ondisk sürümünü oluşturmak için, _inmem alt dizesinin her iki örneğini de _ondisk ile değiştirirsiniz. Bu değişiklikler tabloların ve saklı yordamların adlarını etkiler.

önce _inmem stres iş yükünü çalıştırın

ostress.exe komut satırımızı çalıştırmak için bir RML Cmd İstemi penceresi kullanabilirsiniz. Komut satırı parametreleri ostress'i şu adrese yönlendirir:

  • 100 bağlantıyı eşzamanlı olarak çalıştırın (-n100).
  • Her bağlantının T-SQL betiğini 50 kez çalıştırmasını sağlayın (-r50).
ostress.exe -n100 -r50 -S<servername>.database.windows.net -U<login> -P<password> -d<database> -q -Q"DECLARE @i int = 0, @od SalesLT.SalesOrderDetailType_inmem, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand()* 10000; INSERT INTO @od SELECT OrderQty, ProductID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID= cast((rand()*60) as int); WHILE (@i < 20) begin; EXECUTE SalesLT.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @od; set @i += 1; end"

Önceki ostress.exe komut satırını çalıştırmak için:

  1. Önceki çalıştırmalar tarafından eklenen tüm verileri silmek için SSMS'de aşağıdaki komutu çalıştırarak veritabanı veri içeriğini sıfırlayın:

    EXECUTE Demo.usp_DemoReset;
    
  2. Önceki ostress.exe komut satırının metnini panonuza kopyalayın.

  3. <placeholders> için parametresini -S -U -P -d doğru gerçek değerlerle değiştirin.

  4. Düzenlenmiş komut satırınızı bir RML Cmd penceresinde çalıştırın.

Sonuç bir süredir

ostress.exe tamamlandığında, çalıştırma süresini RML Cmd penceresinde çıktının son satırı olarak yazar. Örneğin, daha kısa bir test çalıştırması yaklaşık 1,5 dakika sürdü:

11/12/15 00:35:00.873 [0x000030A8] OSTRESS exiting normally, elapsed time: 00:01:31.867

Sıfırlama, _ondisk için düzenleme ve yeniden çalıştırma

_inmem çalıştırmasının sonucunu aldıktan sonra, _ondisk çalıştırması için aşağıdaki adımları gerçekleştirin:

  1. Önceki çalıştırma tarafından eklenen tüm verileri silmek için SSMS'de aşağıdaki komutu çalıştırarak veritabanını sıfırlayın:

    EXECUTE Demo.usp_DemoReset;
    
  2. tüm _inmem _ondisk ile değiştirmek için ostress.exe komut satırını düzenleyin.

  3. ostress.exe ikinci kez yeniden çalıştırın ve süre sonucunu yakalayın.

  4. Veritabanını yeniden sıfırlayın (büyük miktarda test verisi olabilecek verileri sorumlu bir şekilde silmek için).

Beklenen karşılaştırma sonuçları

Bellek içi testlerimiz, bu basit iş yükü için performansın dokuz kat arttığını ve veritabanıyla ostress aynı Azure bölgesinde bir Azure VM üzerinde çalıştığını gösterdi.

3. Bellek içi analiz örneğini yükleyin

Bu bölümde, bir columnstore dizini kullanırken GÇ ve istatistik sonuçlarını geleneksel bir b ağacı diziniyle karşılaştıracaksınız.

OLTP iş yükünde gerçek zamanlı analiz için genellikle en iyisi kümelenmemiş columnstore dizini kullanmaktır. Ayrıntılar için bkz . Columnstore Dizinleri Açıklanan.

Columnstore analiz testini hazırlama

  1. kullanarak WITH REPLACEdaha önce yüklediğiniz mevcut veritabanının üzerine yazarak SQL yönetilen örneğinize yeni AdventureWorksLT bir veritabanı geri yükleyin.

    RESTORE DATABASE [AdventureWorksLT] 
    FROM URL = 'https://mitutorials.blob.core.windows.net/examples/AdventureWorksLT2022.bak'
    WITH REPLACE;
    
  2. sql_in memory_analytics_sample panonuza kopyalayın.

    • T-SQL betiği, 1. adımda oluşturduğunuz örnek veritabanında gerekli bellek içi nesneleri AdventureWorksLT oluşturur.
    • Betik boyut tabloları ve iki olgu tablosu oluşturur. Olgu tabloları her birinde 3,5 milyon satırla doldurulur.
    • Betiğin tamamlanması 15 dakika sürebilir.
  3. T-SQL betiğini SSMS'ye yapıştırın ve betiği yürütün. deyimindeki CREATE INDEX COLUMNSTORE anahtar sözcüğü çok önemlidir:CREATE NONCLUSTERED COLUMNSTORE INDEX ...;

  4. En son uyumluluk düzeyi olan SQL Server 2022 (160) olarak ayarlayın AdventureWorksLT : ALTER DATABASE AdventureworksLT SET compatibility_level = 160;

Anahtar tablolar ve columnstore dizinleri

  • dbo.FactResellerSalesXL_CCI, veri düzeyinde gelişmiş sıkıştırmaya sahip kümelenmiş columnstore dizini olan bir tablodur.

  • dbo.FactResellerSalesXL_PageCompressed, yalnızca sayfa düzeyinde sıkıştırılmış eşdeğer bir normal kümelenmiş dizine sahip bir tablodur.

4. Columnstore dizinini karşılaştırmak için anahtar sorgular

Performans geliştirmelerini görmek için çalıştırabileceğiniz birkaç T-SQL sorgu türü vardır. T-SQL betiğinin 2. adımında bu sorgu çiftine dikkat edin. Yalnızca bir satırda farklılık gösterir:

  • FROM FactResellerSalesXL_PageCompressed AS a
  • FROM FactResellerSalesXL_CCI AS a

Kümelenmiş columnstore dizini tabloda yer alır FactResellerSalesXL_CCI .

Aşağıdaki T-SQL betiği, her sorgu için SET STATISTICS GÇ ve SET STATISTICS TIME kullanarak mantıksal G/Ç etkinliği ve zaman istatistiklerini yazdırır.

/*********************************************************************
Step 2 -- Overview
-- Page Compressed BTree table v/s Columnstore table performance differences
-- Enable actual Query Plan in order to see Plan differences when Executing
*/
-- Ensure Database is in 130 compatibility mode
ALTER DATABASE AdventureworksLT SET compatibility_level = 160
GO

-- Execute a typical query that joins the Fact Table with dimension tables
-- Note this query will run on the Page Compressed table, Note down the time
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO

SELECT c.Year
    ,e.ProductCategoryKey
    ,FirstName + ' ' + LastName AS FullName
    ,count(SalesOrderNumber) AS NumSales
    ,sum(SalesAmount) AS TotalSalesAmt
    ,Avg(SalesAmount) AS AvgSalesAmt
    ,count(DISTINCT SalesOrderNumber) AS NumOrders
    ,count(DISTINCT a.CustomerKey) AS CountCustomers
FROM FactResellerSalesXL_PageCompressed AS a
INNER JOIN DimProduct AS b ON b.ProductKey = a.ProductKey
INNER JOIN DimCustomer AS d ON d.CustomerKey = a.CustomerKey
Inner JOIN DimProductSubCategory AS e on e.ProductSubcategoryKey = b.ProductSubcategoryKey
INNER JOIN DimDate AS c ON c.DateKey = a.OrderDateKey
GROUP BY e.ProductCategoryKey,c.Year,d.CustomerKey,d.FirstName,d.LastName
GO
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
GO


-- This is the same Prior query on a table with a clustered columnstore index CCI
-- The comparison numbers are even more dramatic the larger the table is (this is an 11 million row table only)
SET STATISTICS IO ON
SET STATISTICS TIME ON
GO
SELECT c.Year
    ,e.ProductCategoryKey
    ,FirstName + ' ' + LastName AS FullName
    ,count(SalesOrderNumber) AS NumSales
    ,sum(SalesAmount) AS TotalSalesAmt
    ,Avg(SalesAmount) AS AvgSalesAmt
    ,count(DISTINCT SalesOrderNumber) AS NumOrders
    ,count(DISTINCT a.CustomerKey) AS CountCustomers
FROM FactResellerSalesXL_CCI AS a
INNER JOIN DimProduct AS b ON b.ProductKey = a.ProductKey
INNER JOIN DimCustomer AS d ON d.CustomerKey = a.CustomerKey
Inner JOIN DimProductSubCategory AS e on e.ProductSubcategoryKey = b.ProductSubcategoryKey
INNER JOIN DimDate AS c ON c.DateKey = a.OrderDateKey
GROUP BY e.ProductCategoryKey,c.Year,d.CustomerKey,d.FirstName,d.LastName
GO

SET STATISTICS IO OFF
SET STATISTICS TIME OFF
GO

SQL yönetilen örneği yapılandırmanıza bağlı olarak, geleneksel dizinle karşılaştırıldığında kümelenmiş columnstore dizinini kullanarak bu sorgu için önemli performans kazançları bekleyebilirsiniz.