Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
platí pro:SQL Server
azure SQL Database
Přehled
Tato ukázka předvádí funkci OLTP v paměti. Zobrazuje tabulky optimalizované pro paměť a nativně zkompilované uložené procedury a lze je použít k předvedení výhod výkonu OLTP v paměti.
Poznámka
Chcete-li zobrazit tento článek pro SQL Server 2014 (12.x), přečtěte si Rozšíření AdventureWorks k demonstrování In-Memory OLTP.
Ukázka migruje pět tabulek v databázi AdventureWorks2025 na optimalizaci pro paměť a zahrnuje ukázkové zatížení pro zpracování prodejních objednávek. Tuto ukázkovou úlohu můžete použít k zobrazení výhod výkonu při použití OLTP v paměti na vašem serveru.
V popisu ukázky probereme kompromisy, které byly provedeny při migraci tabulek do OLTP v paměti, aby se zohlednily funkce, které nejsou (ještě) podporované pro tabulky optimalizované pro paměť.
Dokumentace této ukázky je strukturovaná takto:
Předpoklady pro instalaci ukázky a spuštění demonstrační úlohy.
Pokyny pro instalování ukázky In-Memory OLTP vycházející z AdventureWorks.
Popis ukázkových tabulek a postupů – obsahuje popisy tabulek a procedur přidaných
AdventureWorks2025ukázkou OLTP v paměti a také důležité informace o migraci některých původníchAdventureWorks2025tabulek pro optimalizaci paměti.Pokyny pro měření výkonu pomocí ukázkové úlohy – včetně pokynů pro instalaci a spuštění ostress, nástroje pro řízení úlohy a spuštění samotné ukázkové úlohy.
Požadavky
-
SQL Server 2016 (13.x)
Pro testování výkonu server se specifikacemi podobnými jako v produkčním prostředí. Pro tuto konkrétní ukázku byste měli mít k dispozici alespoň 16 GB paměti pro SQL Server. Obecné pokyny k hardwaru pro OLTP v paměti najdete v následujícím blogovém příspěvku: Aspekty hardwaru pro In-Memory OLTP na SQL Serveru
Nainstalujte ukázku paměťového OLTP založenou na AdventureWorks
Při instalaci ukázky postupujte takto:
Stáhněte si
AdventureWorks2016_EXT.bakaSQLServer2016Samples.zipz: https://github.com/microsoft/sql-server-samples/releases/tag/adventureworks do místní složky, napříkladC:\Temp.Obnovení zálohy databáze pomocí Transact-SQL nebo aplikace SQL Server Management Studio:
Identifikujte cílovou složku a název souboru dat, například:
H:\DATA\AdventureWorks2022_Data.mdfIdentifikujte cílovou složku a název souboru protokolu, například:
I:\DATA\AdventureWorks2022_log.ldf- Soubor protokolu by se měl umístit na jinou jednotku než datový soubor, ideálně na jednotku s nízkou latencí, jako je úložiště SSD nebo PCIe, pro dosažení maximálního výkonu.
Ukázkový skript T-SQL:
RESTORE DATABASE [AdventureWorks2022] FROM DISK = N'C:\temp\AdventureWorks2022.bak' WITH FILE = 1, MOVE N'AdventureWorks2022_Data' TO N'h:\DATA\AdventureWorks2022_Data.mdf', MOVE N'AdventureWorks2022_Log' TO N'i:\DATA\AdventureWorks2022_log.ldf', MOVE N'AdventureWorks2022_mod' TO N'h:\data\AdventureWorks2022_mod' GOPokud chcete zobrazit ukázkové skripty a úlohy, rozbalte soubor
SQLServer2016Samples.zipdo místní složky. Pokyny ke spuštění úlohy najdete v souboruIn-Memory OLTP\readme.txt.
Popis ukázkových tabulek a postupů
Vzor vytvoří nové tabulky pro produkty a prodejní objednávky na základě existujících tabulek v AdventureWorks2025. Schéma nových tabulek je podobné existujícím tabulkám s několika rozdíly, jak je vysvětleno dále v této části.
Nové tabulky optimalizované pro paměť mají příponu _inmem. Ukázka také obsahuje odpovídající tabulky s příponou _ondisk – tyto tabulky lze použít k porovnání mezi výkonem tabulek optimalizovaných pro paměť a tabulek založených na disku ve vašem systému.
Tabulky optimalizované pro paměť používané v úloze pro porovnání výkonu jsou plně odolné a plně protokolované. Nenabízejí stálost ani spolehlivost, aby dosáhli zvýšení výkonu.
Cílovou úlohou pro tuto ukázku je zpracování prodejních objednávek, kde zvažujeme také informace o produktech a slevách. K tomuto účelu používáme tabulky SalesOrderHeader, SalesOrderDetail, Product, SpecialOffera SpecialOfferProduct.
Dvě nové uložené procedury, Sales.usp_InsertSalesOrder_inmem a Sales.usp_UpdateSalesOrderShipInfo_inmem, se používají k vložení prodejních objednávek a k aktualizaci informací o expedici dané prodejní objednávky.
Nová Demo schématu obsahuje pomocné tabulky a uložené procedury pro provedení ukázkové úlohy.
Konkrétně In-Memory ukázka OLTP přidá do AdventureWorks2025následující objekty:
Tabulky přidané vzorovým souborem
Nové tabulky
Sales.SalesOrderHeader_inmem
- Záhlaví informací o prodejních objednávkách Každá prodejní objednávka má v této tabulce jeden řádek.
Sales.SalesOrderDetail_inmem
- Podrobnosti o prodejních objednávkách Každá položka řádku prodejní objednávky má v této tabulce jeden řádek.
Sales.SpecialOffer_inmem
- Informace o speciálních nabídkách, včetně procenta slevy spojeného s každou speciální nabídkou.
Sales.SpecialOfferProduct_inmem
- Referenční tabulka pro srovnání akčních nabídek a produktů Každá speciální nabídka může obsahovat nula nebo více produktů a každý produkt může být zahrnut v nule nebo více speciálních nabídkách.
Production.Product_inmem
- Informace o produktech, včetně jejich ceníkové ceny.
Demo.DemoSalesOrderDetailSeed
- Používá se v ukázkové úloze k vytvoření ukázkových prodejních objednávek.
Varianty tabulek založené na disku:
Sales.SalesOrderHeader_ondiskSales.SalesOrderDetail_ondiskSales.SpecialOffer_ondiskSales.SpecialOfferProduct_ondiskProduction.Product_ondisk
Rozdíly mezi původními tabulkami založenými na disku a novými tabulkami optimalizovanými pro paměť
Nové tabulky zavedené touto ukázkou obvykle používají stejné sloupce a stejné datové typy jako původní tabulky. Existuje však několik rozdílů. Uvádíme rozdíly v této části spolu s odůvodněním změn.
Sales.SalesOrderHeader_inmem
Výchozí omezení jsou podporována pro tabulky optimalizované pro paměť a většinu výchozích omezení jsme migrovali bez změny. Původní tabulka
Sales.SalesOrderHeadervšak obsahuje dvě výchozí omezení, která načítají aktuální datum pro sloupceOrderDateaModifiedDate. V úloze zpracování s vysokou propustností a velkou souběžností se může jakýkoli globální prostředek stát bodem sporu. Systémový čas je globální zdroj a zjistili jsme, že může představovat úzké hrdlo při spuštění úlohy In-Memory OLTP, která vkládá prodejní objednávky, zejména pokud je potřeba načíst systémový čas pro více sloupců v záhlaví prodejní objednávky a detaily prodejní objednávky. Problém je vyřešený v této ukázce načtením systémového času pouze jednou pro každou vloženou prodejní objednávku a použitím této hodnoty pro sloupce datetime vSalesOrderHeader_inmemaSalesOrderDetail_inmemv uložené proceduřeSales.usp_InsertSalesOrder_inmem.Alias uživatelsky definované datové typy (UDT) – původní tabulka používá dva aliasy UDT
dbo.OrderNumberadbo.AccountNumberpro sloupcePurchaseOrderNumberaAccountNumber. SQL Server 2016 (13.x) nepodporuje alias UDT pro tabulky optimalizované pro paměť, takže nové tabulky používají systémové datové typy nvarchar(25) a nvarchar(15).Sloupce s možnou hodnotou null v klíčích indexu – v původní tabulce má sloupec
SalesPersonIDhodnotu null, zatímco v nových tabulkách sloupec nemá hodnotu null a má výchozí omezení s hodnotou (-1). Důvodem je, že indexy v tabulkách optimalizovaných pro paměť nemohou mít v klíči indexu sloupce s možnou hodnotou null; -1 je v tomto případě náhradní hodnotou NULL.Vypočítané sloupce – Počítané sloupce
SalesOrderNumberaTotalDuejsou vynechány, protože SQL Server 2016 (13.x) nepodporuje počítané sloupce v tabulkách optimalizovaných pro paměť. Nové zobrazeníSales.vSalesOrderHeader_extended_inmemodráží sloupceSalesOrderNumberaTotalDue. Toto zobrazení proto můžete použít, pokud jsou tyto sloupce potřeba.- Platí pro: SQL Server 2017 (14.x). Počínaje SQL Serverem 2017 (14.x) se počítané sloupce podporují v tabulkách a indexech optimalizovaných pro paměť.
omezení cizího klíče jsou podporována pro tabulky optimalizované pro paměť v SQL Serveru 2016 (13.x), ale pouze pokud jsou odkazované tabulky také optimalizovány pro paměť. Cizí klíče, které odkazují na tabulky, jež jsou také migrovány jako optimalizované pro paměť, se zachovávají v těchto migrovaných tabulkách, zatímco ostatní cizí klíče jsou vynechány. Kromě toho
SalesOrderHeader_inmemje horká tabulka v ukázkové úloze a omezení cizích klíčů vyžadují dodatečné zpracování pro všechny operace DML, protože vyžaduje vyhledávání ve všech ostatních tabulkách odkazovaných v těchto omezeních. Proto předpokládáme, že aplikace zajistí referenční integrituSales.SalesOrderHeader_inmemtabulky a při vložení řádků se neověří referenční integrita.Sloupec rowguid je vynechán. I když se u tabulek optimalizovaných pro paměť podporuje uniqueidentifier, možnost ROWGUIDCOL není v SQL Serveru 2016 (13.x) podporovaná. Sloupce tohoto typu se obvykle používají buď pro slučování replikací, nebo pro tabulky, které obsahují filestream sloupce. Tato ukázka neobsahuje ani jedno.
Prodej.PoložkaObjednávky
Výchozí omezení – podobně jako
SalesOrderHeadervýchozí omezení vyžadující systémové datum a čas se nemigruje. Místo toho se uložená procedura, která vkládá prodejní objednávky, postará o vložení aktuálního systémového data a času při prvním vložení.Vypočítané sloupce – vypočítaný sloupec
LineTotalnebyl migrován, protože počítané sloupce nejsou podporované v tabulkách optimalizovaných pro paměť v SQL Serveru 2016 (13.x). Pro přístup k tomuto sloupci použijte zobrazeníSales.vSalesOrderDetail_extended_inmem.Rowguid – sloupec
rowguidje vynechán. Podrobnosti najdete v popisu tabulkySalesOrderHeader.
Výroba.Produkt
UDT alias – původní tabulka používá uživatelsky definovaný datový typ
dbo.Flag, který je ekvivalentní systémovému datovému typu bit. Migrovaná tabulka místo toho používá datový typ bitů.Rowguid – sloupec
rowguidje vynechán. Podrobnosti najdete v popisu tabulkySalesOrderHeader.
Prodej.SpeciálníNabídka
-
Rowguid – sloupec
rowguidje vynechán. Podrobnosti najdete v popisu tabulkySalesOrderHeader.
Prodej.ZvláštníNabídkaProdukt
-
Rowguid – sloupec
rowguidje vynechán. Podrobnosti najdete v popisu tabulkySalesOrderHeader.
Důležité informace o indexech v tabulkách optimalizovaných pro paměť
Směrný index pro tabulky optimalizované pro paměť je index NONCLUSTERED, který podporuje bodová vyhledávání (vyhledávání indexu na predikátu rovnosti), prohledávání rozsahů (prohledávání indexu v predikátu nerovnosti), úplné prohledávání indexu a seřazené prohledávání. Kromě toho indexy NONCLUSTERED podporují vyhledávání na úvodních sloupcích klíče indexu. Ve skutečnosti indexy optimalizované pro paměť podporují všechny operace podporované neclusterovanými indexy založené na disku, přičemž jedinou výjimkou je zpětná kontrola. Proto je použití NEKLASTROVANÝCH indexů bezpečnou volbou pro vaše indexy.
Indexy HASH je možné použít k další optimalizaci úlohy. Jsou optimalizované pro vyhledávání bodů a vkládání řádků. Je však nutné vzít v úvahu, že nepodporují prohledávání rozsahů, seřazené skenování nebo vyhledávání na vedoucích sloupcích klíče indexu. Proto je potřeba při použití těchto indexů věnovat pozornost. Kromě toho je nutné zadat bucket_count při vytváření. Obvykle by měla být nastavena mezi jednou a dvěma násobky počtu hodnot klíče indexu, ale nadhodnocení obvykle není problém.
Další informace:
Indexy migrovaných tabulek byly vyladěny pro ukázkové úlohy zpracování prodejních objednávek. Úloha spoléhá na vkládání a bodové vyhledávání v tabulkách Sales.SalesOrderHeader_inmem a Sales.SalesOrderDetail_inmema také spoléhá na vyhledávání bodů na sloupcích primárního klíče v tabulkách Production.Product_inmem a Sales.SpecialOffer_inmem.
Sales.SalesOrderHeader_inmem má tři indexy, které jsou všechny HASH indexy kvůli výkonu a protože pro úlohu nejsou potřeba žádné seřazené skeny ani skeny rozsahu.
Index HASH na (
SalesOrderID): bucket_count má velikost 10 milionů (zaokrouhleno nahoru na 16 milionů), protože očekávaný počet prodejních objednávek je 10 milionů.HASH index na (
SalesPersonID): bucket_count je 1 milion. Poskytnutá datová sada nemá mnoho obchodních zástupců. Ale toto velké "bucket_count" umožňuje budoucí růst. Navíc neplatíte pokutu za bodové vyhledávání, pokud je bucket_count překilován.HASH index na (
CustomerID): bucket_count je 1 milion. Zadaná datová sada nemá mnoho zákazníků, ale to umožňuje budoucí růst.
Sales.SalesOrderDetail_inmem má tři indexy, které jsou všechny HASH indexy kvůli výkonu a protože pro úlohu nejsou potřeba žádné seřazené skeny ani skeny rozsahu.
Index HASH pro (
SalesOrderID,SalesOrderDetailID): toto je index primárního klíče, a i když vyhledávání (SalesOrderID,SalesOrderDetailID) jsou občasné, použití indexu hash pro klíč urychlí vkládání řádků. Bucket_count má velikost 50 milionů (zaokrouhleno nahoru na 67 milionů): očekávaný počet prodejních objednávek je 10 milionů a velikost je v průměru pět položek na objednávku.Index HASH pro (
SalesOrderID): vyhledávání podle prodejní objednávky je časté: Chcete najít všechny řádkové položky odpovídající jedné objednávce. Očekávaný počet prodejních objednávek je 10 milionů, proto má bucket_count velikost 10 milionů (zaokrouhleno nahoru na 16 milionů).HASH index na (
ProductID): bucket_count je 1 milion. Zadaná datová sada nemá mnoho produktů, ale to umožňuje budoucí růst.
Production.Product_inmem má tři indexy
Index HASH on (
ProductID): vyhledávání naProductIDjsou v kritické cestě pro ukázkovou úlohu, proto se jedná o index hash.NONCLUSTERED index on (
Name): To umožňuje uspořádané prohledávání názvů produktů.NEKLASTROVANÝ index na (
ProductNumber): To umožňuje uspořádané procházení čísel produktů.
Sales.SpecialOffer_inmem má jeden index HASH (SpecialOfferID): vyhledávání bodů speciálních nabídek je v kritické části ukázkové úlohy.
bucket_count má velikost 1 milion, aby umožnil budoucí růst.
Sales.SpecialOfferProduct_inmem není zmíněn v ukázkové zátěži, a proto není zřejmá potřeba použít hash indexy pro optimalizaci této tabulky – indexy na (SpecialOfferID, ProductID) a (ProductID) jsou neklastrové.
V předchozím příkladu jsou některé počty záznamů nadměrné, ale ne počty záznamů pro indexy SalesOrderHeader_inmem a SalesOrderDetail_inmem: ty jsou určeny pouze pro 10 milionů prodejních objednávek. To bylo provedeno tak, aby bylo možné nainstalovat ukázku do systémů s nízkou dostupností paměti, i když v takových případech ukázková úloha selže s chybou nedostatku paměti. Pokud chcete škálovat mnohem více než 10 milionů prodejních objednávek, můžete počet kontejnerů odpovídajícím způsobem zvýšit.
Důležité informace o využití paměti
Využití paměti v ukázkové databázi, a to jak před a po spuštění ukázkové úlohy, je popsáno v části Využití paměti pro tabulky optimalizované pro paměť.
Uložené procedury přidané vzorkem
Dva klíčové uložené procedury pro vložení prodejní objednávky a aktualizaci podrobností o expedici jsou následující:
Sales.usp_InsertSalesOrder_inmemVloží do databáze novou prodejní objednávku a vypíše
SalesOrderIDpro danou prodejní objednávku. Jako vstupní parametry přebírá podrobnosti pro záhlaví prodejní objednávky a řádkové položky v objednávce.Výstupní parametr:
-
@SalesOrderID int –
SalesOrderIDpro prodejní objednávku, která byla právě vložena
-
@SalesOrderID int –
Vstupní parametry (povinné):
- @DueDatedatetime2
- @CustomerIDint
- @BillToAddressIDint
- @ShipToAddressIDint
- @ShipMethodIDint
-
@SalesOrderDetails
Sales.SalesOrderDetailType_inmem- parametr hodnotového typu tabulky (TVP) který obsahuje řádkové položky objednávky
Vstupní parametry (volitelné):
- @Statustinyint
- @OnlineOrderFlagbit
- @PurchaseOrderNumbernvarchar(25)
- @AccountNumbernvarchar(15)
- @SalesPersonIDint
- @TerritoryIDint
- @CreditCardIDint
- @CreditCardApprovalCodevarchar(15)
- @CurrencyRateIDint
- @Commentnvarchar(128)
Sales.usp_UpdateSalesOrderShipInfo_inmemAktualizujte informace o expedici pro danou prodejní objednávku. Tím se také aktualizují informace o expedici pro všechny řádkové položky prodejní objednávky.
Jedná se o zástupnou proceduru pro nativně zkompilované uložené procedury
Sales.usp_UpdateSalesOrderShipInfo_natives logikou opakování, která řeší (neočekávané) konflikty se souběžnými transakcemi, které aktualizují stejnou objednávku. Další informace najdete v tématu logiky opakování.
Sales.usp_UpdateSalesOrderShipInfo_native- Jedná se o nativně zkompilovanou uloženou proceduru, která skutečně zpracovává aktualizaci expedičních informací. Je určena k volání z obalové uložené procedury
Sales.usp_UpdateSalesOrderShipInfo_inmem. Pokud se klient dokáže vypořádat se selháními a implementuje logiku opakování, můžete tento postup volat přímo, místo abyste použili obalovou uloženou proceduru.
- Jedná se o nativně zkompilovanou uloženou proceduru, která skutečně zpracovává aktualizaci expedičních informací. Je určena k volání z obalové uložené procedury
Pro ukázkové úlohy se používá následující uložená procedura.
Demo.usp_DemoReset- Obnoví ukázku vyprázdněním a znovu osazením tabulek
SalesOrderHeaderaSalesOrderDetail.
- Obnoví ukázku vyprázdněním a znovu osazením tabulek
Následující uložené procedury se používají k vkládání a odstraňování z tabulek optimalizovaných pro paměť a současně zaručují integritu domény a referenční integrity.
Production.usp_InsertProduct_inmemProduction.usp_DeleteProduct_inmemSales.usp_InsertSpecialOffer_inmemSales.usp_DeleteSpecialOffer_inmemSales.usp_InsertSpecialOfferProduct_inmem
Nakonec se k ověření domény a referenční integrity používá následující uložená procedura.
dbo.usp_ValidateIntegrityVolitelný parametr: @object_id – ID objektu k ověření integrity pro
Tento postup spoléhá na tabulky
dbo.DomainIntegrity,dbo.ReferentialIntegrityadbo.UniqueIntegritypro pravidla integrity, která je potřeba ověřit – ukázka naplní tyto tabulky na základě kontrol, cizího klíče a jedinečných omezení, která existují pro původní tabulky v databáziAdventureWorks2025.Spoléhá na pomocné postupy
dbo.usp_GenerateCKCheck,dbo.usp_GenerateFKCheckadbo.GenerateUQCheckk vygenerování T-SQL potřebného k provádění kontrol integrity.
Měření výkonu pomocí ukázkové úlohy
ostress je nástroj příkazového řádku vyvinutý týmem podpory Microsoft CSS SQL Serveru. Tento nástroj lze použít ke spouštění dotazů nebo paralelnímu spouštění uložených procedur. Můžete nakonfigurovat počet vláken pro paralelní spuštění daného příkazu T-SQL a můžete určit, kolikrát má být příkaz proveden v tomto vlákně; ostress roztáčí vlákna a spustí příkaz na všech vláknech paralelně. Po ukončení provádění všech vláken ostress oznámí čas potřebný k dokončení provádění všech vláken.
Nainstalujte ostress
ostress se instaluje jako součást nástrojů RML (Report Markup Language). pro ostress neexistuje samostatná instalace.
Postup instalace:
Stáhněte a spusťte instalační balíček x64 pro nástroje RML z následující stránky: Stáhnout RML pro SQL Server
Pokud se zobrazí dialogové okno s informací, že se některé soubory používají, vyberte Pokračovat.
Spustit ostress
Ostress se spouští z příkazového řádku. Nejpohodlnější je spustit nástroj z příkazového řádku RML, který je nainstalovaný jako součást nástrojů RML.
Pokud chcete otevřít příkazový řádek RML, postupujte podle těchto pokynů:
Ve Windows otevřete nabídku Start tak, že vyberete klávesu Windows a zadáte rml. Vyberte příkazový řádek RML, který je v seznamu výsledků hledání.
Ujistěte se, že je příkazový řádek umístěný v instalační složce nástrojů RML.
Možnosti příkazového řádku pro ostress lze zobrazit, když jednoduše běží ostress.exe bez možností příkazového řádku. Hlavní možnosti, které je vhodné zvážit při spuštění ostress s touto ukázkou , jsou následující:
| Možnost | Description |
|---|---|
-S |
Název instance SQL Serveru, ke které se chcete připojit. |
-E |
Použití ověřování systému Windows k připojení (výchozí); pokud používáte ověřování SQL Serveru, použijte možnosti -U a -P zadejte uživatelské jméno a heslo. |
-d |
Název databáze, v tomto příkladu AdventureWorks2025. |
-Q |
Příkaz T-SQL, který se má spustit. |
-n |
Počet připojení zpracovávající každý vstupní soubor nebo dotaz |
-r |
Počet iterací pro každé připojení ke spuštění každého vstupního souboru nebo dotazu. |
Ukázková úloha
Hlavní uložená procedura použitá v ukázkové úloze je Sales.usp_InsertSalesOrder_inmem/ondisk. Skript v následujícím příkladu vytvoří parametr s tabulkovou hodnotou (TVP) s příkladovými daty a zavolá proceduru pro vložení prodejní objednávky s pěti položkami na řádcích.
Nástroj ostress slouží k paralelnímu spouštění volání uložených procedur k simulaci klientů vkládajících prodejní objednávky souběžně.
Po každém spuštění zátěže resetujte demonstraci Demo.usp_DemoReset. Tento postup odstraní řádky v tabulkách optimalizovaných pro paměť, zkrátí diskové tabulky a spustí kontrolní bod databáze.
Následující skript se spustí souběžně, aby simuloval úlohu zpracování prodejních objednávek:
DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_inmem, @SalesOrderID AS INT, @DueDate AS DATETIME2 = sysdatetime(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS INT = (RAND() * 5) + 1;
INSERT INTO @od
SELECT OrderQty,
ProductID,
SpecialOfferID
FROM Demo.DemoSalesOrderDetailSeed
WHERE OrderID = CAST ((RAND() * 106) + 1 AS INT);
WHILE (@i < 20)
BEGIN
EXECUTE Sales.usp_InsertSalesOrder_inmem
@SalesOrderID OUTPUT,
@DueDate,
@CustomerID,
@BillToAddressID,
@ShipToAddressID,
@ShipMethodID,
@od;
SET @i + = 1;
END
Ve skriptu je každá vytvořená vzorová objednávka 20krát vložena pomocí 20 uložených procedur, které jsou spuštěny ve smyčce WHILE. Smyčka se používá k zohlednění skutečnosti, že se databáze používá k vytvoření pořadí vzorků. V typických produkčních prostředích aplikace střední vrstvy vytváří prodejní objednávku k vložení.
Předchozí skript vloží prodejní objednávky do tabulek optimalizovaných pro paměť. Skript pro vložení prodejních objednávek do tabulek založených na disku je odvozen nahrazením dvou výskytů _inmem s _ondisk.
Pomocí nástroje ostress spustíme skripty pomocí několika souběžných připojení. Tento parametr -n používáme k řízení počtu připojení a parametru r , abychom mohli řídit, kolikrát se skript provádí na každém připojení.
Spustit úlohu
Abychom mohli testovat ve velkém měřítku, vložíme 10 milionů prodejních objednávek pomocí 100 připojení. Tento test běží přiměřeně dobře na skromném serveru (například s 8 fyzickými a 16 logickými jádry) a základním úložišti SSD pro protokol. Pokud test na vašem hardwaru nefunguje dobře, projděte si část Řešení potíží s pomalými testy. Pokud chcete snížit úroveň stresu pro tento test, snižte počet připojení změnou parametru -n. Pokud chcete například snížit počet připojení na 40, změňte parametr -n100 na -n40.
Jako měřítko výkonu pro úlohu používáme uplynulý čas, jak je hlášeno ostress.exe po spuštění úlohy.
Následující pokyny a měření používají úlohu, která vloží 10 milionů prodejních objednávek. Pokyny ke spuštění úlohy s omezeným zatížením, které vkládají 1 milion prodejních objednávek, najdete v instrukcích v In-Memory OLTP\readme.txt, které jsou součástí archivu SQLServer2016Samples.zip.
Tabulky optimalizované pro paměť
Začneme spuštěním úlohy v tabulkách optimalizovaných pro paměť. Následující příkaz otevře 100 vláken, z nichž každá běží pro 5 000 iterací. Každá iterace vloží 20 prodejních objednávek do samostatných transakcí. K dispozici je 20 vložení na iteraci, které kompenzují skutečnost, že se databáze používá ke generování dat, která se mají vložit. Výsledkem je celkem 20 × 5 000 × 100 = 10 000 000 vložení prodejní objednávky.
Otevřete příkazový řádek RML a spusťte následující příkaz:
Výběrem tlačítka Kopírovat příkaz zkopírujte a vložte ho do příkazového řádku nástrojů RML.
ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_inmem, @SalesOrderID AS INT, @DueDate AS DATETIME2 = SYSDATETIME(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS INT = (RAND() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID = CAST ((RAND() * 106) + 1 AS INT); WHILE (@i < 20) BEGIN EXECUTE Sales.usp_InsertSalesOrder_inmem @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; SET @i + = 1; END"
Na jednom testovacím serveru s celkovým počtem 8 fyzických (16 logických) jader to trvalo 2 minuty a 5 sekund. Na druhém testovacím serveru s 24 fyzickými (48 logickými) jádry to trvalo 1 minutu a 0 sekund.
Sledujte využití procesoru, když je úloha spuštěná, například pomocí správce úloh. Vidíte, že využití procesoru je blízko 100%. Pokud tomu tak není, máte úzké hrdlo u protokolových vstupně-výstupních operací, viz také řešení potíží s pomalými testy.
Diskové tabulky
Následující příkaz spustí úlohu v tabulkách založených na discích. Spuštění této úlohy může chvíli trvat, což je do velké míry způsobeno kolizemi synchronizačních zámků v systému. Tabulky optimalizované pro paměť jsou bez západky, a proto netrpí tímto problémem.
Otevřete příkazový řádek RML a spusťte následující příkaz:
Výběrem tlačítka Kopírovat příkaz zkopírujte a vložte ho do příkazového řádku nástrojů RML.
ostress.exe -n100 -r5000 -S. -E -dAdventureWorks2022 -q -Q"DECLARE @i AS INT = 0, @od AS Sales.SalesOrderDetailType_ondisk, @SalesOrderID AS INT, @DueDate AS DATETIME2 = sysdatetime(), @CustomerID AS INT = RAND() * 8000, @BillToAddressID AS INT = RAND() * 10000, @ShipToAddressID AS INT = RAND() * 10000, @ShipMethodID AS INT = (RAND() * 5) + 1; INSERT INTO @od SELECT OrderQty, ProductID, SpecialOfferID FROM Demo.DemoSalesOrderDetailSeed WHERE OrderID = CAST ((RAND() * 106) + 1 AS INT); WHILE (@i < 20) BEGIN EXECUTE Sales.usp_InsertSalesOrder_ondisk @SalesOrderID OUTPUT, @DueDate, @CustomerID, @BillToAddressID, @ShipToAddressID, @ShipMethodID, @od; SET @i + = 1; END"
Na jednom testovacím serveru s celkovým počtem 8 fyzických (16 logických) jader to trvalo 41 minut a 25 sekund. Na druhém testovacím serveru s 24 fyzickými (48 logickými) jádry to trvalo 52 minut a 16 sekund.
Hlavním faktorem rozdílu výkonu mezi tabulkami optimalizovanými pro paměť a diskovými tabulkami v tomto testu je to, že při použití tabulek založených na disku sql Server nemůže plně využívat procesor. Důvodem je konflikt zámků: souběžné transakce se pokouší zapsat na stejnou datovou stránku; západky se používají k zajištění, že pouze jedna transakce může zapisovat na stránku najednou. Modul In-Memory OLTP je bez západky a řádky dat nejsou uspořádané na stránkách. Souběžné transakce tedy navzájem neblokují vložení, což umožňuje SQL Serveru plně využívat procesor.
Využití procesoru můžete sledovat, když je úloha spuštěná, například pomocí správce úloh. U tabulek založených na disku je využití procesoru daleko od 100%. Při testovací konfiguraci s 16 logickými procesory by se využití pohybovalo kolem 24%.
Volitelně můžete pomocí nástroje Performance Monitor zobrazit číslo západek za sekundu s čítačem výkonu \SQL Server:Latches\Latch Waits/sec.
Resetování demoverze
Pokud chcete ukázku resetovat, otevřete příkazový řádek RML a spusťte následující příkaz:
ostress.exe -S. -E -dAdventureWorks2022 -Q"EXEC Demo.usp_DemoReset"
V závislosti na hardwaru to může trvat několik minut.
Po každém spuštění ukázky doporučujeme resetovat. Vzhledem k tomu, že tato úloha je pouze vkládací, každé spuštění spotřebovává více paměti, a proto je nutné resetovat, aby se předešlo nedostatku paměti. Množství paměti spotřebované po spuštění je popsáno v oddílu Využití paměti po spuštění úlohy.
Řešení problémů s pomalu běžícími testy
Výsledky testů se obvykle liší podle hardwaru a také úrovně souběžnosti používané při testovacím běhu. Pokud výsledky nejsou očekávané, podívejte se na několik věcí:
Počet souběžných transakcí: Při spouštění úlohy v jednom vlákně je zvýšení výkonu s In-Memory OLTP pravděpodobně menší než 2X. Kolize západek je pouze významným problémem, pokud existuje vysoká úroveň souběžnosti.
Nízký počet jader dostupných pro SQL Server: To znamená, že v systému existuje nízká úroveň souběžnosti, protože pro SQL je k dispozici pouze tolik souběžných transakcí, kolik je k dispozici.
- Příznak: Pokud je vysoké využití procesoru při spouštění úloh na tabulkách založených na disku, znamená to, že je malý prostor pro kolize, což poukazuje na nedostatek souběžnosti.
Rychlost jednotky protokolu: Pokud jednotka protokolu nemůže držet krok s úrovní propustnosti transakcí v systému, dochází ke zúžení výkonu na vstupně-výstupních operacích protokolu. Ačkoliv je logování efektivnější s In-Memory OLTP, pokud je logovací IO kritickým bodem, potenciální zvýšení výkonu je omezený.
- Příznak: Pokud využití CPU není blízko 100% nebo je při spouštění úloh na tabulkách optimalizovaných pro paměť velmi kolísavé, může docházet k úzkému místu v logu IO. To můžete potvrdit otevřením aplikace Resource Monitor a zobrazením délky fronty protokolové jednotky.
Využití paměti a místa na disku v ukázce
V následujícím příkladu popisujeme, co očekávat z hlediska využití paměti a místa na disku pro ukázkovou databázi. Zobrazíme také výsledky na testovacím serveru s 16 logickými jádry.
Využití paměti pro tabulky optimalizované pro paměť
Celkové využití databáze
Následující dotaz lze použít k získání celkového využití paměti pro In-Memory OLTP v systému.
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Snímek po vytvoření databáze:
| typ | Jméno | pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Výchozí | 94 |
| MEMORYCLERK_XTP | DB_ID_5 | 877 |
| MEMORYCLERK_XTP | Výchozí | 0 |
| MEMORYCLERK_XTP | Výchozí | 0 |
Standardní správci paměti obsahují systémové struktury paměti a jsou relativně malé. Správce paměti pro uživatelskou databázi, v tomto případě databázi s ID 5 (tento database_id se může lišit ve vašem vlastním případu), je asi 900 MB.
Využití paměti na tabulku
Pomocí následujícího dotazu můžete přejít k podrobnostem o využití paměti jednotlivých tabulek a jejich indexů:
SELECT object_name(t.object_id) AS [Table name],
memory_allocated_for_table_kb,
memory_allocated_for_indexes_kb
FROM sys.dm_db_xtp_table_memory_stats AS dms
INNER JOIN sys.tables AS t
ON dms.object_id = t.object_id
WHERE t.type = 'U';
Následující tabulka zobrazuje výsledky tohoto dotazu pro čerstvou instalaci ukázky:
| Název tabulky | memory_allocated_for_table_kb |
memory_allocated_for_indexes_kb |
|---|---|---|
SpecialOfferProduct_inmem |
64 | 3840 |
DemoSalesOrderHeaderSeed |
1984 | 5504 |
SalesOrderDetail_inmem |
15316 | 663552 |
DemoSalesOrderDetailSeed |
64 | 10432 |
SpecialOffer_inmem |
3 | 8192 |
SalesOrderHeader_inmem |
7168 | 147456 |
Product_inmem |
124 | 12352 |
Jak vidíte, tabulky jsou poměrně malé: SalesOrderHeader_inmem je asi 7 MB a SalesOrderDetail_inmem je o velikosti přibližně 15 MB.
To, co je zde zajímavé, je velikost paměti přidělené indexům v porovnání s velikostí dat tabulky. Je to proto, že indexy hash v ukázce jsou předem nastaveny pro větší velikost dat. Indexy hash mají pevnou velikost, a proto se jejich velikost nezvětší s velikostí dat v tabulce.
Využití paměti po spuštění úlohy
Po vložení 10 milionů prodejních objednávek vypadá využití veškeré paměti podobně jako v následujícím dotazu:
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Tady je soubor výsledků.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Výchozí | 146 |
| MEMORYCLERK_XTP | DB_ID_5 | 7374 |
| MEMORYCLERK_XTP | Výchozí | 0 |
| MEMORYCLERK_XTP | Výchozí | 0 |
Jak vidíte, SQL Server používá pro tabulky optimalizované pro paměť a indexy v ukázkové databázi bitovou velikost pod 8 GB.
Zobrazení podrobného využití paměti pro jednotlivé tabulky po jednom vzorovém spuštění:
SELECT object_name(t.object_id) AS [Table name],
memory_allocated_for_table_kb,
memory_allocated_for_indexes_kb
FROM sys.dm_db_xtp_table_memory_stats AS dms
INNER JOIN sys.tables AS t
ON dms.object_id = t.object_id
WHERE t.type = 'U';
Tady je soubor výsledků.
Table name |
memory_allocated_for_table_kb |
memory_allocated_for_indexes_kb |
|---|---|---|
| SalesOrderDetail_inmem | 5113761 | 663552 |
| DemoDetailProdejníObjednávkySemínko | 64 | 10368 |
| SpecialOffer_inmem | 2 | 8192 |
| SalesOrderHeader_inmem | 1575679 | 147456 |
| Product_inmem | 111 | 12032 |
| SpeciálníNabídkaProdukt_inmem | 64 | 3712 |
| DemoSalesOrderHeaderSeed | 1984 | 5504 |
Vidíme celkem přibližně 6,5 GB dat. Velikost indexů v tabulce SalesOrderHeader_inmem a SalesOrderDetail_inmem je stejná jako velikost indexů před vložením prodejních objednávek. Velikost indexu se nezměnila, protože obě tabulky používají indexy hash a indexy hash jsou statické.
Po resetování demo
Uložená procedura Demo.usp_DemoReset může být použita k resetování ukázky. Odstraní data v tabulkách SalesOrderHeader_inmem a SalesOrderDetail_inmemznovu uloží data z původních tabulek SalesOrderHeader a SalesOrderDetail.
I když byly řádky v tabulkách odstraněny, neznamená to, že se paměť okamžitě uvolní. SQL Server podle potřeby uvolní paměť z odstraněných řádků v tabulkách optimalizovaných pro paměť na pozadí. Vidíte, že okamžitě po demo resetu, kdy na systému není žádná transakční úloha, paměť z odstraněných řádků ještě není uvolněna.
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Tady je soubor výsledků.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Výchozí | 2261 |
| MEMORYCLERK_XTP | DB_ID_5 | 7396 |
| MEMORYCLERK_XTP | Výchozí | 0 |
| MEMORYCLERK_XTP | Výchozí | 0 |
Očekává se to: paměť se uvolní, když je spuštěná transakční úloha.
Pokud spustíte druhé spuštění ukázkové úlohy, zpočátku se využití paměti sníží, protože dříve odstraněné řádky jsou odstraněny. V určitém okamžiku se velikost paměti znovu zvýší, dokud se úloha nedokončí. Po vložení 10 milionů řádků po ukázkovém resetování je využití paměti velmi podobné využití po prvním spuštění. Například:
SELECT type,
name,
pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';
Tady je soubor výsledků.
type |
name |
pages_MB |
|---|---|---|
| MEMORYCLERK_XTP | Výchozí | 1863 |
| MEMORYCLERK_XTP | DB_ID_5 | 7390 |
| MEMORYCLERK_XTP | Výchozí | 0 |
| MEMORYCLERK_XTP | Výchozí | 0 |
Využití disku pro tabulky optimalizované pro paměť
Celkovou velikost disku pro soubory kontrolních bodů databáze v daném okamžiku najdete pomocí dotazu:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Počáteční stav
Když se zpočátku vytvoří ukázková skupina souborů a ukázkové tabulky optimalizované pro paměť, vytvoří se několik souborů kontrolních bodů a systém začne vyplňovat soubory – počet předem vytvořených souborů kontrolních bodů závisí na počtu logických procesorů v systému. Vzhledem k tomu, že je ukázka zpočátku velmi malá, předem vytvořené soubory jsou po počátečním vytvoření většinou prázdné.
Následující kód ukazuje počáteční velikost na disku pro ukázku na počítači s 16 logickými procesory:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Tady je soubor výsledků.
| Velikost na disku v MB |
|---|
| 2312 |
Jak vidíte, mezi velikostí souborů kontrolního bodu na disku, což je 2,3 GB, a skutečnou velikostí datových souborů, která je blíže 30 MB, je velká nesrovnalost.
Když se podíváte blíže na to, odkud pochází využití místa na disku, můžete použít následující dotaz. Velikost disku vráceného tímto dotazem je přibližná pro soubory se stavem 5 (VYŽADOVÁNO PRO ZÁLOHOVÁNÍ/HA), 6 (V PŘEVODU NA TOMBSTONE) nebo 7 (TOMBSTONE).
SELECT state_desc,
file_type_desc,
COUNT(*) AS [count],
SUM(CASE WHEN state = 5 AND file_type = 0 THEN 128 * 1024 * 1024
WHEN state = 5 AND file_type = 1 THEN 8 * 1024 * 1024
WHEN state IN (6, 7) THEN 68 * 1024 * 1024
ELSE file_size_in_bytes END) / 1024 / 1024 AS [on-disk size MB]
FROM sys.dm_db_xtp_checkpoint_files
GROUP BY state, state_desc, file_type, file_type_desc
ORDER BY state, file_type;
V případě počátečního stavu ukázky vypadá výsledek přibližně jako následující tabulka pro server s 16 logickými procesory:
| state_desc | popis_typu_souboru | počítat | velikost disku MB |
|---|---|---|---|
| PŘEDEM VYTVOŘENO | DATA | 16 | 2048 |
| PŘEDEM VYTVOŘENO | DELTA | 16 | 128 |
| VE VÝSTAVBĚ | DATA | 1 | 128 |
| VE VÝSTAVBĚ | DELTA | 1 | 8 |
Jak vidíte, většina místa je využívána předem vytvořenými daty a rozdílovými soubory. SQL Server předem vytvořil jeden pár souborů (data, delta) na logický procesor. Datové soubory jsou navíc předem nastavené na 128 MB a rozdílové soubory na 8 MB pro efektivnější vkládání dat do těchto souborů.
Skutečná data v tabulkách optimalizovaných pro paměť jsou v jednom datovém souboru.
Po spuštění úlohy
Po jednom testovacím spuštění, které vloží 10 milionů prodejních objednávek, vypadá celková velikost na disku přibližně takto (pro 16jádrový testovací server):
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Tady je soubor výsledků.
| Velikost na disku v MB |
|---|
| 8828 |
Velikost na disku je blízko 9 GB, která se blíží velikosti dat v paměti.
Podrobněji se podíváme na velikosti souborů kontrolních bodů v různých státech:
SELECT state_desc,
file_type_desc,
COUNT(*) AS [count],
SUM(CASE WHEN state = 5 AND file_type = 0 THEN 128 * 1024 * 1024
WHEN state = 5 AND file_type = 1 THEN 8 * 1024 * 1024
WHEN state IN (6, 7) THEN 68 * 1024 * 1024
ELSE file_size_in_bytes END) / 1024 / 1024 AS [on-disk size MB]
FROM sys.dm_db_xtp_checkpoint_files
GROUP BY state, state_desc, file_type, file_type_desc
ORDER BY state, file_type;
Tady je soubor výsledků.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| PŘEDEM VYTVOŘENO | DATA | 16 | 2048 |
| PŘEDEM VYTVOŘENO | DELTA | 16 | 128 |
| VE VÝSTAVBĚ | DATA | 1 | 128 |
| VE VÝSTAVBĚ | DELTA | 1 | 8 |
Stále máme 16 párů předem vytvořených souborů, připravené k přechodu, protože kontrolní body jsou zavřené.
Existuje jeden pár ve výstavbě, který se používá, dokud nebude uzavřen aktuální kontrolní bod. Společně s aktivními kontrolními soubory to poskytuje přibližně 6,5 GB využití disku pro 6,5 GB dat v paměti. Vzpomeňte si, že indexy se neuchovávají na disku, a proto je celková velikost disku menší než velikost v paměti v tomto případě.
Po resetování demo
Po ukázkovém resetování se místo na disku okamžitě neuvolní, pokud v systému neexistuje žádná transakční úloha a neexistují žádné kontrolní body databáze. Aby se soubory kontrolních bodů přesunuly skrze různé fáze a nakonec byly zahozeny, je potřeba provést několik kontrolních bodů a událostí zkrácení protokolu, zahájit sloučení souborů kontrolních bodů a rovněž zahájit odklízení nepotřebných dat. K těmto událostem dochází automaticky, pokud máte v systému transakční pracovní zátěž (a pravidelně zálohujete logy, v případě že používáte model úplného obnovení), ale nedochází k nim, když je systém ve stavu nečinnosti, jako například při ukázkovém scénáři.
V příkladu po ukázkovém resetování se může zobrazit něco takového:
SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]
FROM sys.filegroups AS f
INNER JOIN sys.database_files AS df
ON f.data_space_id = df.data_space_id
WHERE f.type = N'FX';
Tady je soubor výsledků.
| Velikost na disku v MB |
|---|
| 11839 |
Téměř 12 GB je to výrazně větší než 9 GB, které jsme měli před obnovením ukázky. Důvodem je to, že bylo zahájeno sloučení některých kontrolních souborů, ale některé cíle sloučení ještě nejsou nainstalovány a některé zdrojové soubory sloučení ještě nebyly odstraněny, jak je vidět v následujícím příkladu:
SELECT state_desc,
file_type_desc,
COUNT(*) AS [count],
SUM(CASE WHEN state = 5 AND file_type = 0 THEN 128 * 1024 * 1024
WHEN state = 5 AND file_type = 1 THEN 8 * 1024 * 1024
WHEN state IN (6, 7) THEN 68 * 1024 * 1024
ELSE file_size_in_bytes END) / 1024 / 1024 AS [on-disk size MB]
FROM sys.dm_db_xtp_checkpoint_files
GROUP BY state, state_desc, file_type, file_type_desc
ORDER BY state, file_type;
Tady je soubor výsledků.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| PŘEDEM VYTVOŘENO | DATA | 16 | 2048 |
| PŘEDEM VYTVOŘENO | DELTA | 16 | 128 |
| AKTIVNÍ | DATA | 38 | 5152 |
| AKTIVNÍ | DELTA | 38 | 1331 |
| CÍL SLUČOVÁNÍ | DATA | 7 | 896 |
| CÍL SLUČOVÁNÍ | DELTA | 7 | 56 |
| SLOUČENÝ ZDROJ | DATA | 13 | 1772 |
| SLOUČENÝ ZDROJ | DELTA | 13 | 455 |
Cíle sloučení jsou instalovány a sloučené zdroje jsou vyčištěny, jakmile v systému probíhá transakční aktivita.
Po druhém spuštění ukázkové úlohy a vložení 10 milionů prodejních objednávek po resetování ukázky zjistíte, že soubory vytvořené během prvního spuštění úlohy byly odstraněny. Pokud předchozí dotaz spustíte několikrát, když je úloha spuštěná, uvidíte, že soubory kontrolních bodů procházejí různými fázemi.
Po druhém spuštění úlohy, kdy bylo vloženo 10 milionů prodejních objednávek, se využití disků velmi podobá, i když nemusí být nutně stejné jako po prvním spuštění, protože systém je dynamický. Například:
SELECT state_desc,
file_type_desc,
COUNT(*) AS [count],
SUM(CASE WHEN state = 5 AND file_type = 0 THEN 128 * 1024 * 1024
WHEN state = 5 AND file_type = 1 THEN 8 * 1024 * 1024
WHEN state IN (6, 7) THEN 68 * 1024 * 1024
ELSE file_size_in_bytes END) / 1024 / 1024 AS [on-disk size MB]
FROM sys.dm_db_xtp_checkpoint_files
GROUP BY state, state_desc, file_type, file_type_desc
ORDER BY state, file_type;
Tady je soubor výsledků.
state_desc |
file_type_desc |
count |
on-disk size MB |
|---|---|---|---|
| PŘEDEM VYTVOŘENO | DATA | 16 | 2048 |
| PŘEDEM VYTVOŘENO | DELTA | 16 | 128 |
| VE VÝSTAVBĚ | DATA | 2 | 268 |
| VE VÝSTAVBĚ | DELTA | 2 | 16 |
| AKTIVNÍ | DATA | 41 | 5608 |
| AKTIVNÍ | DELTA | 41 | 328 |
V tomto případě jsou ve UNDER CONSTRUCTION stavu dva páry kontrolních bodů, což znamená, že do UNDER CONSTRUCTION stavu bylo přesunuto více párů souborů, pravděpodobně kvůli vysoké úrovni souběžnosti v úloze. Několik souběžných vláken vyžadovalo současně novou dvojici souborů a tím se přesunul pár z PRECREATED do UNDER CONSTRUCTION.