Delen via


Voorbeelddatabase voor OLTP in het geheugen

van toepassing op:SQL ServerAzure SQL Database-

Overzicht

In dit voorbeeld wordt de OLTP-functie in het geheugen getoond. Het toont voor geheugen geoptimaliseerde tabellen en systeemeigen gecompileerde opgeslagen procedures en kan worden gebruikt om prestatievoordelen van OLTP in het geheugen te demonstreren.

Notitie

Zie Extensies voor AdventureWorks om In-Memory OLTP te demonstreren voor dit artikel voor SQL Server 2014 (12.x).

Het voorbeeld migreert vijf tabellen in de AdventureWorks2022-database naar geheugen-geoptimaliseerd en bevat een demoworkload voor de verwerking van verkooporders. U kunt deze demoworkload gebruiken om het prestatievoordeel te zien van het gebruik van OLTP in het geheugen op uw server.

In de beschrijving van het voorbeeld bespreken we de compromissen die zijn gemaakt bij het migreren van de tabellen naar in-memory OLTP om rekening te houden met de functies die (nog) niet worden ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen.

De documentatie van dit voorbeeld is als volgt gestructureerd:

Voorwaarden

  • SQL Server 2016 (13.x)

  • Voor prestatietests is een server met specificaties vergelijkbaar met uw productieomgeving. Voor dit specifieke voorbeeld moet er ten minste 16 GB geheugen beschikbaar zijn voor SQL Server. Zie de volgende blogpost voor algemene richtlijnen voor hardware voor OLTP in het geheugen: Hardwareoverwegingen voor In-Memory OLTP in SQL Server

Het OLTP-voorbeeld in het geheugen installeren op basis van AdventureWorks

Volg deze stappen om het voorbeeld te installeren:

  1. Download AdventureWorks2016_EXT.bak en SQLServer2016Samples.zip van: https://github.com/microsoft/sql-server-samples/releases/tag/adventureworks naar een lokale map, bijvoorbeeld C:\Temp.

  2. Herstel de databaseback-up met behulp van Transact-SQL of SQL Server Management Studio:

    1. Identificeer de doelmap en bestandsnaam voor het gegevensbestand, bijvoorbeeld:

      H:\DATA\AdventureWorks2022_Data.mdf
      
    2. Identificeer de doelmap en bestandsnaam voor het logboekbestand, bijvoorbeeld:

      I:\DATA\AdventureWorks2022_log.ldf
      
      1. Het logboekbestand moet op een ander station worden geplaatst dan het gegevensbestand, in het ideale geval een station met lage latentie, zoals een SSD- of PCIe-opslag, voor maximale prestaties.

    Voorbeeld van T-SQL-script:

    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'
     GO
    
  3. Als u de voorbeeldscripts en workload wilt weergeven, pakt u het bestand SQLServer2016Samples.zip uit in een lokale map. Raadpleeg het bestand In-Memory OLTP\readme.txt voor instructies over het uitvoeren van de workload.

Beschrijving van de voorbeeldtabellen en -procedures

In het voorbeeld worden nieuwe tabellen gemaakt voor producten en verkooporders, op basis van bestaande tabellen in AdventureWorks2022. Het schema van de nieuwe tabellen is vergelijkbaar met de bestaande tabellen, met enkele verschillen, zoals verderop in deze sectie wordt uitgelegd.

De nieuwe tabellen die zijn geoptimaliseerd voor geheugen, dragen het achtervoegsel _inmem. Het voorbeeld bevat ook bijbehorende tabellen met het achtervoegsel _ondisk . Deze tabellen kunnen worden gebruikt om een een-op-een-vergelijking te maken tussen de prestaties van tabellen die zijn geoptimaliseerd voor geheugen en tabellen op basis van schijven op uw systeem.

De tabellen die zijn geoptimaliseerd voor geheugen die in de workload worden gebruikt voor prestatievergelijking, zijn volledig duurzaam en volledig geregistreerd. Ze offeren geen duurzaamheid of betrouwbaarheid op om de prestatiewinst te bereiken.

De doelworkload voor dit voorbeeld is de verwerking van verkooporders, waarbij we ook informatie over producten en kortingen overwegen. Hiervoor gebruiken we de tabellen SalesOrderHeader, SalesOrderDetail, Product, SpecialOfferen SpecialOfferProduct.

Twee nieuwe opgeslagen procedures, Sales.usp_InsertSalesOrder_inmem en Sales.usp_UpdateSalesOrderShipInfo_inmem, worden gebruikt om verkooporders in te voegen en de verzendgegevens van een bepaalde verkooporder bij te werken.

Het nieuwe schema Demo bevat helpertabellen en opgeslagen procedures voor het uitvoeren van een demoworkload.

Concreet voegt het In-Memory OLTP-voorbeeld de volgende objecten toe aan AdventureWorks2022:

Tabellen die door het voorbeeld zijn toegevoegd

De nieuwe tabellen

Sales.SalesOrderHeader_inmem

  • Koptekstinformatie over verkooporders. Elke verkooporder heeft één rij in deze tabel.

Sales.SalesOrderDetail_inmem

  • Details van verkooporders. Elk regelitem van een verkooporder heeft één rij in deze tabel.

Sales.SpecialOffer_inmem

  • Informatie over speciale aanbiedingen, inclusief het kortingspercentage dat aan elke speciale aanbieding is gekoppeld.

Sales.SpecialOfferProduct_inmem

  • Referentietabel tussen speciale aanbiedingen en producten. Elke speciale aanbieding kan nul of meer producten bevatten, en elk product kan in nul of meer speciale aanbiedingen worden opgenomen.

Production.Product_inmem

  • Informatie over producten, inclusief hun catalogusprijs.

Demo.DemoSalesOrderDetailSeed

  • Wordt gebruikt in de demoworkload om voorbeeldverkooporders te maken.

Variaties van tabellen op schijf:

  • Sales.SalesOrderHeader_ondisk

  • Sales.SalesOrderDetail_ondisk

  • Sales.SpecialOffer_ondisk

  • Sales.SpecialOfferProduct_ondisk

  • Production.Product_ondisk

Verschillen tussen de oorspronkelijke schijf en de nieuwe tabellen die zijn geoptimaliseerd voor geheugen

Normaal gesproken gebruiken de nieuwe tabellen die in dit voorbeeld worden geïntroduceerd dezelfde kolommen en dezelfde gegevenstypen als de oorspronkelijke tabellen. Er zijn echter enkele verschillen. We vermelden de verschillen in deze sectie, samen met een reden voor de wijzigingen.

Sales.SalesOrderHeader_inmem

  • Standaardbeperkingen worden ondersteund voor geheugen-geoptimaliseerde tabellen, en de meeste standaardbeperkingen hebben we zoals ze zijn gemigreerd. De oorspronkelijke tabel Sales.SalesOrderHeader bevat echter twee standaardbeperkingen waarmee de huidige datum wordt opgehaald voor de kolommen OrderDate en ModifiedDate. In een workload voor de verwerking van orders met hoge doorvoer en veel gelijktijdigheid kan elke globale resource een conflictpunt worden. Systeemtijd is zo'n globale resource en we hebben vastgesteld dat het een knelpunt kan worden bij het uitvoeren van een In-Memory OLTP-workload waarmee verkooporders worden ingevoegd, met name als de systeemtijd moet worden opgehaald voor meerdere kolommen in de kop van de verkooporder en de details van de verkooporder. Het probleem wordt in dit voorbeeld opgelost door de systeemtijd slechts één keer op te halen voor elke verkooporder die is ingevoegd en die waarde te gebruiken voor de datum/tijd-kolommen in SalesOrderHeader_inmem en SalesOrderDetail_inmem, in de opgeslagen procedure Sales.usp_InsertSalesOrder_inmem.

  • door de gebruiker gedefinieerde aliasgegevenstypen (UDT's): in de oorspronkelijke tabel worden twee alias-UDT's dbo.OrderNumber en dbo.AccountNumbergebruikt voor respectievelijk de kolommen PurchaseOrderNumber en AccountNumber. SQL Server 2016 (13.x) biedt geen ondersteuning voor alias UDT voor tabellen die zijn geoptimaliseerd voor geheugen. De nieuwe tabellen maken dus gebruik van systeemgegevenstypen nvarchar(25) en nvarchar(15).

  • Null-kolommen in indexsleutels : in de oorspronkelijke tabel is de kolom SalesPersonID nullbaar, terwijl in de nieuwe tabellen de kolom niet nullbaar is en een standaardbeperking met waarde (-1). Dit komt doordat indexen voor tabellen die zijn geoptimaliseerd voor geheugen, geen null-kolommen in de indexsleutel kunnen bevatten; -1 is in dit geval een surrogaat voor NULL.

  • Berekende kolommen: de berekende kolommen en SalesOrderNumber worden weggelaten, omdat SQL Server 2016 (13.x) geen berekende kolommen TotalDue ondersteunt in tabellen die zijn geoptimaliseerd voor geheugen. De nieuwe weergave Sales.vSalesOrderHeader_extended_inmem weerspiegelt de kolommen SalesOrderNumber en TotalDue. Daarom kunt u deze weergave gebruiken als deze kolommen nodig zijn.

    • Van toepassing op: SQL Server 2017 (14.x). Vanaf SQL Server 2017 (14.x) worden berekende kolommen ondersteund in tabellen en indexen die zijn geoptimaliseerd voor geheugen.
  • beperkingen voor refererende sleutels worden ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen in SQL Server 2016 (13.x), maar alleen als de tabellen waarnaar wordt verwezen, ook geoptimaliseerd zijn voor geheugen. Vreemde sleutels die verwijzen naar tabellen die ook naar geheugen-geoptimaliseerd worden gemigreerd, worden behouden in de gemigreerde tabellen, terwijl andere vreemde sleutels worden weggelaten. Bovendien is SalesOrderHeader_inmem een hot table in de voorbeeldworkload, en foreign key constraints vereisen extra verwerking voor alle DML-bewerkingen, aangezien dit opzoekacties vereist in alle andere tabellen die door deze beperkingen worden verwezen. Daarom is de veronderstelling dat de app referentiële integriteit voor de Sales.SalesOrderHeader_inmem tabel garandeert en referentiële integriteit niet wordt gevalideerd wanneer rijen worden ingevoegd.

  • Rowguid : de kolom rowguid wordt weggelaten. Hoewel uniqueidentifier wordt ondersteund voor tabellen die zijn geoptimaliseerd voor geheugen, wordt de optie ROWGUIDCOL niet ondersteund in SQL Server 2016 (13.x). Kolommen van dit type worden meestal gebruikt voor merge-replicatie of voor tabellen met filestreamkolommen. Dit voorbeeld bevat geen van beide.

Verkoop.VerkooporderDetail

  • Standaardbeperkingen : vergelijkbaar met SalesOrderHeaderde standaardbeperking waarvoor de systeemdatum/-tijd is vereist, wordt niet gemigreerd. In plaats daarvan zorgt de opgeslagen procedure voor het invoegen van verkooporders voor het invoegen van de huidige systeemdatum/-tijd bij eerste invoeging.

  • Berekende kolommen : de berekende kolom LineTotal is niet gemigreerd omdat berekende kolommen niet worden ondersteund met tabellen die zijn geoptimaliseerd voor geheugen in SQL Server 2016 (13.x). Gebruik de Sales.vSalesOrderDetail_extended_inmem weergave om toegang te krijgen tot deze kolom.

  • Rowguid- : de kolom rowguid wordt weggelaten. Zie de beschrijving voor de tabel SalesOrderHeadervoor meer informatie.

Productie.Product

  • alias-UDT's: de oorspronkelijke tabel maakt gebruik van het door de gebruiker gedefinieerde gegevenstype dbo.Flag, wat gelijk is aan de bit van het systeemgegevenstype. In de gemigreerde tabel wordt in plaats daarvan het bitgegevenstype gebruikt.

  • Rowguid- : de kolom rowguid wordt weggelaten. Zie de beschrijving voor de tabel SalesOrderHeadervoor meer informatie.

Verkoop.SpecialeAanbieding

  • Rowguid- : de kolom rowguid wordt weggelaten. Zie de beschrijving voor de tabel SalesOrderHeadervoor meer informatie.

Verkoop.SpecialeAanbiedingProduct

  • Rowguid- : de kolom rowguid wordt weggelaten. Zie de beschrijving voor de tabel SalesOrderHeadervoor meer informatie.

Overwegingen voor indexen voor tabellen die zijn geoptimaliseerd voor geheugen

De basislijnindex voor tabellen die zijn geoptimaliseerd voor geheugen is de INDEX NONCLUSTERED, die puntzoekopdrachten (indexzoeken op gelijkheidspredicaat) ondersteunt, bereikscans (indexzoeken in ongelijkheidspredicaat), volledige indexscans en geordende scans. Daarnaast ondersteunen NIET-GECLUSTERDE indexen zoeken op voorloopkolommen van de indexsleutel. In feite ondersteunen niet-geclusterde indexen die zijn geoptimaliseerd voor geheugen alle bewerkingen die worden ondersteund door niet-geclusterde indexen op schijf, met de enige uitzondering dat achterwaartse scans worden uitgevoerd. Daarom is het gebruik van NIET-GECLUSTERDE indexen een veilige keuze voor uw indexen.

HASH-indexen kunnen worden gebruikt om de workload verder te optimaliseren. Ze zijn geoptimaliseerd voor puntzoekacties en rijinvoegingen. U moet er echter rekening mee houden dat ze geen ondersteuning bieden voor bereikscans, geordende scans of zoekopdrachten op belangrijke indexsleutelkolommen. Daarom moet u ervoor zorgen dat u deze indexen gebruikt. Daarnaast is het nodig om de bucket_count tijdens het aanmaken te specificeren. Het moet meestal berekend worden op een waarde tussen een en twee keer het aantal indexsleutelwaarden, maar een overschatting is meestal geen probleem.

Voor meer informatie:

De indexen in de gemigreerde tabellen zijn afgestemd op de workload voor de verwerking van demo-verkooporders. De werkbelasting is afhankelijk van invoegingen en puntzoekacties in de tabellen Sales.SalesOrderHeader_inmem en Sales.SalesOrderDetail_inmemen is ook afhankelijk van puntzoekacties op de primaire-sleutelkolommen in de tabellen Production.Product_inmem en Sales.SpecialOffer_inmem.

Sales.SalesOrderHeader_inmem heeft drie indexen, die alle HASH-indexen zijn om de prestaties te verbeteren, en omdat er geen geordende scans of bereikscans nodig zijn van de workload.

  • HASH-index op (SalesOrderID): bucket_count is ingesteld op 10 miljoen (afgerond naar 16 miljoen), omdat het verwachte aantal verkooporders 10 miljoen is.

  • HASH-index op (SalesPersonID): bucket_count is 1 miljoen. De verstrekte gegevensset heeft niet veel verkopers. Maar deze grote bucket_count maakt toekomstige groei mogelijk. Bovendien betaalt u geen prestatiestraf voor puntzoekacties als de bucket_count te groot is.

  • HASH-index op (CustomerID): bucket_count is 1 miljoen. De opgegeven gegevensset heeft niet veel klanten, maar dit zorgt voor toekomstige groei.

Sales.SalesOrderDetail_inmem heeft drie indexen, die alle HASH-indexen zijn om de prestaties te verbeteren, en omdat er geen geordende scans of bereikscans nodig zijn van de workload.

  • HASH-index op (SalesOrderID, SalesOrderDetailID): dit is de primaire sleutelindex, en hoewel zoekacties op (SalesOrderID, SalesOrderDetailID) infrequent zijn, versnelt het gebruik van een hash-index voor de sleutel het invoegen van rijen. De bucket_count is 50 miljoen (afgerond op 67 miljoen): het verwachte aantal verkooporders is 10 miljoen en dit is een gemiddelde van vijf artikelen per order

  • HASH-index op (SalesOrderID): zoeken op verkooporder komt vaak voor: u wilt alle artikelen vinden die bij één order horen. De bucket_count is vastgesteld op 10 miljoen (afgerond naar boven op 16 miljoen), omdat het verwachte aantal verkooporders 10 miljoen is.

  • HASH-index op (ProductID): bucket_count is 1 miljoen. De opgegeven gegevensset heeft niet veel producten, maar dit zorgt voor toekomstige groei.

Production.Product_inmem heeft drie indexen

  • HASH-index op (ProductID): zoekacties op ProductID bevinden zich in het kritieke pad voor de demo-werkbelasting, daarom is dit een hash-index.

  • Niet-geclusterde index op (Name): hiermee kunnen geordende scans van productnamen mogelijk worden gemaakt.

  • NIET-GECLUSTERDE index op (ProductNumber): hiermee kunnen geordende scans van productnummers worden uitgevoerd

Sales.SpecialOffer_inmem heeft één HASH-index op (SpecialOfferID): puntzoekacties van speciale aanbiedingen bevinden zich in het kritieke deel van de demoworkload. De bucket_count heeft een grootte van 1 miljoen om toekomstige groei mogelijk te maken.

Sales.SpecialOfferProduct_inmem wordt niet verwezen in de demoworkload en er is dus geen duidelijk noodzaak om hash-indexen in deze tabel te gebruiken om de workload te optimaliseren. De indexen op (SpecialOfferID, ProductID) en (ProductID) zijn NIET GECLUSTERD.

In het vorige voorbeeld zijn sommige bucketaantallen te groot, maar niet de bucketaantallen voor de indexen op SalesOrderHeader_inmem en SalesOrderDetail_inmem: ze zijn geschikt voor slechts 10 miljoen verkooporders. Dit is gedaan om het installeren van het voorbeeldbestand toe te staan op systemen met weinig beschikbaar geheugen, hoewel in die gevallen de demo workload mislukt met een geheugentekort. Als u meer dan 10 miljoen verkooporders wilt schalen, kunt u het aantal buckets dienovereenkomstig verhogen.

Overwegingen voor geheugengebruik

Geheugengebruik in de voorbeelddatabase, zowel vóór als na het uitvoeren van de demoworkload, wordt besproken in de sectie Geheugengebruik voor de tabellen die zijn geoptimaliseerd voor geheugen.

Opgeslagen procedures toegevoegd door het voorbeeld

De twee belangrijke opgeslagen procedures voor het invoegen van verkooporders en het bijwerken van verzendgegevens zijn als volgt:

  • Sales.usp_InsertSalesOrder_inmem

    • Hiermee wordt een nieuwe verkooporder in de database ingevoerd en de SalesOrderID voor die verkooporder wordt weergegeven. Als invoerparameters worden details voor de koptekst van de verkooporder en de regelitems in de order gebruikt.

    • Uitvoerparameter:

      • @SalesOrderID int : de SalesOrderID voor de verkooporder die zojuist is ingevoegd
    • Invoerparameters (vereist):

      • @DueDatedatetime2
      • @CustomerIDint
      • @BillToAddressIDint
      • @ShipToAddressIDint
      • @ShipMethodIDint
      • Sales.SalesOrderDetailType_inmem@SalesOrderDetails - parameter met tabelwaarde (TVP) die de regelitems van de order bevat
    • Invoerparameters (optioneel):

      • @Statustinyint
      • @OnlineOrderFlagbit
      • @PurchaseOrderNumbernvarchar(25)
      • @AccountNumbernvarchar(15)
      • @SalesPersonIDint
      • @TerritoryIDint
      • @CreditCardIDint
      • @CreditCardApprovalCodevarchar(15)
      • @CurrencyRateIDint
      • @Commentnvarchar(128)
  • Sales.usp_UpdateSalesOrderShipInfo_inmem

    • Werk de verzendgegevens voor een bepaalde verkooporder bij. Hiermee worden ook de verzendgegevens bijgewerkt voor alle regelitems van de verkooporder.

    • Dit is een wrapperprocedure voor de systeemeigen gecompileerde opgeslagen procedures Sales.usp_UpdateSalesOrderShipInfo_native, met herhalingslogica om (onverwachte) potentiële conflicten aan te pakken die ontstaan door gelijktijdige transacties bij het bijwerken van dezelfde bestelling. Zie logica voor opnieuw proberenvoor meer informatie.

  • Sales.usp_UpdateSalesOrderShipInfo_native

    • Dit is de systeemeigen gecompileerde opgeslagen routine die de update daadwerkelijk verwerkt naar de verzendinformatie. Het is bedoeld om aan te roepen vanuit de opgeslagen wrapper-procedure Sales.usp_UpdateSalesOrderShipInfo_inmem. Als de client fouten kan verwerken en logica voor opnieuw proberen kan implementeren, kunt u deze procedure rechtstreeks aanroepen in plaats van de opgeslagen procedure van de wrapper te gebruiken.

De volgende opgeslagen procedure wordt gebruikt voor de demoworkload.

  • Demo.usp_DemoReset

    • De demo opnieuw instellen door de tabellen SalesOrderHeader en SalesOrderDetail leeg te maken en opnieuw te vullen.

De volgende opgeslagen procedures worden gebruikt voor het invoegen en verwijderen van tabellen die zijn geoptimaliseerd voor geheugen, terwijl domein- en referentiële integriteit worden gegarandeerd.

  • Production.usp_InsertProduct_inmem
  • Production.usp_DeleteProduct_inmem
  • Sales.usp_InsertSpecialOffer_inmem
  • Sales.usp_DeleteSpecialOffer_inmem
  • Sales.usp_InsertSpecialOfferProduct_inmem

Ten slotte wordt de volgende opgeslagen procedure gebruikt om domein- en referentiële integriteit te verifiëren.

  1. dbo.usp_ValidateIntegrity

    • Optionele parameter: @object_id - id van het object om integriteit te valideren voor

    • Deze procedure is afhankelijk van de tabellen dbo.DomainIntegrity, dbo.ReferentialIntegrityen dbo.UniqueIntegrity voor de integriteitsregels die moeten worden geverifieerd. In het voorbeeld worden deze tabellen ingevuld op basis van de controle, refererende sleutel en unieke beperkingen die bestaan voor de oorspronkelijke tabellen in de AdventureWorks2022-database.

    • Het is afhankelijk van de helperprocedures dbo.usp_GenerateCKCheck, dbo.usp_GenerateFKChecken dbo.GenerateUQCheck om de T-SQL te genereren die nodig is voor het uitvoeren van de integriteitscontroles.

Prestatiemetingen met behulp van de demoworkload

ostress is een opdrachtregelprogramma dat is ontwikkeld door het microsoft CSS SQL Server-ondersteuningsteam. Dit hulpprogramma kan worden gebruikt om query's uit te voeren of opgeslagen procedures parallel uit te voeren. U kunt het aantal threads configureren om een bepaalde T-SQL-instructie parallel uit te voeren en u kunt opgeven hoe vaak de instructie moet worden uitgevoerd op deze thread; ostress draait de threads op en voert de instructie parallel uit op alle threads. Nadat de uitvoering voor alle threads is voltooid, rapporteert ostress de tijd die nodig is voor alle threads om de uitvoering te voltooien.

Ostress installeren

ostress is geïnstalleerd als onderdeel van de RML-hulpprogramma's (Report Markup Language); er is geen zelfstandige installatie voor ostress.

Installatiestappen:

  1. Download en voer het x64-installatiepakket voor de RML-hulpprogramma's op de volgende pagina uit: RML voor SQL Server downloaden

  2. Als er een dialoogvenster is waarin staat dat bepaalde bestanden worden gebruikt, selecteert u Doorgaan

Voer ostress uit

Ostress wordt uitgevoerd vanaf de opdrachtregelprompt. Het is het handigst om het hulpprogramma uit te voeren vanaf de RML Cmd Prompt, die is geïnstalleerd als onderdeel van de RML-hulpprogramma's.

Volg deze instructies om de RML Cmd-prompt te openen:

Open in Windows het startmenu door de Windows-toets te selecteren en rmlte typen. Selecteer RML Cmd Prompt, die zich in de lijst met zoekresultaten bevindt.

Zorg ervoor dat de opdrachtprompt zich in de installatiemap van RML-hulpprogramma's bevindt.

De opdrachtregelopties voor ostress kunnen worden gezien wanneer u gewoon zonder opdrachtregelopties uitvoert ostress.exe . De belangrijkste opties die u kunt overwegen voor het uitvoeren van ostress met dit voorbeeld zijn als volgt:

Optie Description
-S De naam van het SQL Server-exemplaar waarmee verbinding moet worden gemaakt.
-E Windows-verificatie gebruiken om verbinding te maken (standaard); Als u SQL Server-verificatie gebruikt, gebruikt u de opties -U en -P geeft u respectievelijk de gebruikersnaam en het wachtwoord op.
-d Naam van de database, voor dit voorbeeld AdventureWorks2022.
-Q De T-SQL-instructie die moet worden uitgevoerd.
-n Het aantal verbindingen dat elk invoerbestand/elke invoerquery verwerkt.
-r Het aantal iteraties voor elke verbinding om elk invoerbestand/query uit te voeren.

Demo workload

De belangrijkste opgeslagen procedure die in de demoworkload wordt gebruikt, is Sales.usp_InsertSalesOrder_inmem/ondisk. Het script in het volgende voorbeeld maakt een tabelwaardeparameter (TVP) met voorbeeldgegevens en roept de procedure aan om een verkooporder met vijf regelitems in te voegen.

Het ostress-hulpprogramma wordt gebruikt om de opgeslagen procedureaanroepen parallel uit te voeren om clients die gelijktijdig verkooporders invoegen te simuleren.

Stel de demo opnieuw in na elke stressuitvoering die Demo.usp_DemoResetuitvoert. Met deze procedure worden de rijen in de geheugen-geoptimaliseerde tabellen verwijderd, worden de schijfgebaseerde tabellen ingekort en wordt er een databasecontrolepunt uitgevoerd.

Het volgende script wordt gelijktijdig uitgevoerd om een workload voor de verwerking van verkooporders te simuleren:

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

Met dit script wordt elke voorbeeldorder die is gemaakt 20 keer ingevoegd, via 20 opgeslagen procedures uitgevoerd in een WHILE-lus. De lus wordt gebruikt om rekening te houden met het feit dat de database wordt gebruikt om de voorbeeldvolgorde samen te stellen. In typische productieomgevingen maakt de toepassing in de middellaag de verkooporder die moet worden ingevoegd.

Met het vorige script worden verkooporders ingevoegd in tabellen die zijn geoptimaliseerd voor geheugen. Het script voor het invoegen van verkooporders in schijftabellen wordt afgeleid door de twee voorkomens van _inmem te vervangen door _ondisk.

We gebruiken het ostress-hulpprogramma om de scripts uit te voeren met behulp van verschillende gelijktijdige verbindingen. We gebruiken de parameter -n om het aantal verbindingen te beheren en de parameter r om te bepalen hoe vaak het script wordt uitgevoerd op elke verbinding.

De workload uitvoeren

Om te testen op schaal voegen we 10 miljoen verkooporders in met behulp van 100 verbindingen. Deze test wordt redelijk uitgevoerd op een bescheiden server (bijvoorbeeld 8 fysieke, 16 logische kernen) en eenvoudige SSD-opslag voor het logboek. Als de test niet goed presteert op uw hardware, raadpleegt u de sectie Problemen met trage tests oplossen. Als u het stressniveau voor deze test wilt verminderen, verlaagt u het aantal verbindingen door de parameter -nte wijzigen. Als u bijvoorbeeld het aantal verbindingen wilt verlagen naar 40, wijzigt u de parameter -n100 in -n40.

Voor prestatiemeting van de workload gebruiken we de verstreken tijd, zoals gerapporteerd nadat de workload is uitgevoerd door ostress.exe.

De volgende instructies en metingen gebruiken een workload waarmee 10 miljoen verkooporders worden ingevoegd. Zie de instructies in In-Memory OLTP\readme.txt, dat onderdeel is van het SQLServer2016Samples.zip-archief, voor instructies over het uitvoeren van een verkleinde workload die 1 miljoen verkooporders invoegt.

Tabellen die zijn geoptimaliseerd voor geheugen

We beginnen met het uitvoeren van de workload op tabellen die zijn geoptimaliseerd voor geheugen. Met de volgende opdracht worden 100 threads geopend, die elk worden uitgevoerd voor 5000 iteraties. Elke iteratie voegt 20 verkooporders in afzonderlijke transacties in. Er zijn 20 invoegingen per iteratie om te compenseren dat de database wordt gebruikt om de gegevens te genereren die moeten worden ingevoegd. Dit levert in totaal 20 * 5.000 * 100 = 10.000.000 verkooporderinvoegingen op.

Open de RML Cmd-prompt en voer de volgende opdracht uit:

Selecteer de knop Kopiëren om de opdracht te kopiëren en plak deze in de opdrachtprompt RML Utilities.

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"

Op één testserver met een totaal aantal van 8 fysieke (16 logische) kernen duurde dit 2 minuten en 5 seconden. Op een tweede testserver met 24 fysieke (48 logische) kernen duurde dit 1 minuut en 0 seconden.

Bekijk het CPU-gebruik terwijl de workload wordt uitgevoerd, bijvoorbeeld met behulp van taakbeheer. U ziet dat het CPU-gebruik bijna 100%is. Als dit niet het geval is, heeft u een log IO-knelpunt. Zie ook Problemen met traag uitgevoerde tests oplossen.

Tabellen op basis van schijven

Met de volgende opdracht wordt de workload uitgevoerd op schijftabellen. Het kan even duren voordat deze workload wordt uitgevoerd, wat grotendeels te wijten is aan vergrendelingsconflicten in het systeem. Tabellen die zijn geoptimaliseerd voor geheugen, zijn vergrendelingsvrij en hebben dus geen last van dit probleem.

Open de RML Cmd-prompt en voer de volgende opdracht uit:

Selecteer de knop Kopiëren om de opdracht te kopiëren en plak deze in de opdrachtprompt RML Utilities.

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"

Op één testserver met een totaal van 8 fysieke (16 logische) kernen duurde dit 41 minuten en 25 seconden. Op een tweede testserver met 24 fysieke (48 logische) kernen duurde dit 52 minuten en 16 seconden.

De belangrijkste factor in het prestatieverschil tussen tabellen die zijn geoptimaliseerd voor geheugen en tabellen op basis van schijven in deze test, is dat SQL Server niet volledig gebruik kan maken van de CPU wanneer u schijftabellen gebruikt. De reden hiervoor is vergrendelingsconflict: gelijktijdige transacties proberen naar dezelfde gegevenspagina te schrijven; vergrendelingen worden gebruikt om ervoor te zorgen dat slechts één transactie tegelijk naar een pagina kan schrijven. De In-Memory OLTP-engine is vergrendelingsvrij en gegevensrijen worden niet geordend op pagina's. Gelijktijdige transacties blokkeren dus elkaars invoegingen niet, waardoor SQL Server volledig gebruik kan maken van de CPU.

U kunt het CPU-gebruik observeren terwijl de workload wordt uitgevoerd, bijvoorbeeld met taakbeheer. U ziet dat het CPU-gebruik van schijftabellen ver van 100%is. Bij een testconfiguratie met 16 logische processors zou het gebruik rond de 24%liggen.

Optioneel kunt u het aantal wachttijden per seconde bekijken met Performance Monitor, met de prestatiemeter \SQL Server:Latches\Latch Waits/sec.

De demo opnieuw instellen

Als u de demo opnieuw wilt instellen, opent u de RML Cmd-prompt en voert u de volgende opdracht uit:

ostress.exe -S. -E -dAdventureWorks2022 -Q"EXEC Demo.usp_DemoReset"

Afhankelijk van de hardware kan dit enkele minuten duren.

We raden u aan om na elke demo opnieuw in te stellen. Omdat deze werktaak alleen invoegt, verbruikt elke uitvoering meer geheugen en is er dus een reset vereist om het geheugen niet uit te putten. De hoeveelheid geheugen die na een uitvoering wordt verbruikt, wordt besproken in sectie geheugengebruik na het uitvoeren van de workload.

Problemen met trage tests verhelpen

Testresultaten variëren doorgaans met hardware en ook het niveau van gelijktijdigheid dat wordt gebruikt in de testuitvoering. Een aantal dingen die u moet zoeken als de resultaten niet zoals verwacht zijn:

  • Aantal gelijktijdige transacties: bij het uitvoeren van de workload op één thread is de prestatiewinst met In-Memory OLTP waarschijnlijk minder dan 2X. Vergrendelingsconflicten zijn slechts een belangrijk probleem als er sprake is van een hoge mate van gelijktijdigheid.

  • Laag aantal kernen dat beschikbaar is voor SQL Server: dit betekent dat er een laag gelijktijdigheidsniveau is in het systeem, omdat er slechts zoveel gelijktijdige uitvoeringen van transacties kunnen zijn als er kernen beschikbaar zijn voor SQL.

    • Symptoom: Als de CPU-belasting hoog is tijdens het uitvoeren van de workload op schijftabellen, betekent dit dat er niet veel conflicten zijn, wat wijst op een gebrek aan concurrentie.
  • Snelheid van het logboekstation: als het logboekstation het transactiedoorvoerniveau in het systeem niet kan bijhouden, ontstaat er een knelpunt in de logboek-IO van de workload. Hoewel logboekregistratie efficiënter is met In-Memory OLTP, is de potentiële prestatiewinst beperkt als logboek-IO een knelpunt is.

    • Symptoom: als het CPU-gebruik niet dicht bij 100% ligt of erg stekelig is bij het uitvoeren van de workload op tabellen die zijn geoptimaliseerd voor geheugen, is er mogelijk een IO-knelpunt in het logboek. Dit kan worden bevestigd door Resource Monitor te openen en de wachtrijlengte voor de log-schijf te bekijken.

Geheugen- en schijfruimtegebruik in het voorbeeld

In het volgende voorbeeld beschrijven we wat u kunt verwachten in termen van geheugen- en schijfruimtegebruik voor de voorbeelddatabase. We tonen ook de resultaten van een testserver met 16 logische kernen.

Geheugengebruik voor de tabellen die zijn geoptimaliseerd voor geheugen

Algemeen gebruik van de database

De volgende query kan worden gebruikt om het totale geheugengebruik voor In-Memory OLTP in het systeem te verkrijgen.

SELECT type,
       name,
       pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';

Momentopname nadat de database zojuist is gemaakt:

soort naam pages_MB
MEMORYCLERK_XTP Verstek 94
MEMORYCLERK_XTP DB_ID_5 877
MEMORYCLERK_XTP Verstek 0
MEMORYCLERK_XTP Verstek 0

De standaardgeheugenmedewerkers bevatten systeembrede geheugenstructuren en zijn relatief klein. De geheugenbeheerder voor de gebruikersdatabase, in dit geval de database met ID 5 (de database_id kan verschillen in uw instantie), is ongeveer 900 MB.

Geheugengebruik per tabel

De volgende query kan worden gebruikt om in te zoomen op het geheugengebruik van de afzonderlijke tabellen en de bijbehorende indexen:

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

In de volgende tabel ziet u de resultaten van deze query voor een nieuwe installatie van het voorbeeld:

Tabelnaam 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

Zoals u kunt zien, zijn de tabellen vrij klein: SalesOrderHeader_inmem ongeveer 7 MB en SalesOrderDetail_inmem ongeveer 15 MB groot.

Wat hier opvallend is, is de grootte van het geheugen dat is toegewezen voor indexen, vergeleken met de grootte van de tabelgegevens. Dat komt doordat de hash-indexen in het voorbeeld worden gepresized voor een grotere gegevensgrootte. Hash-indexen hebben een vaste grootte en hun grootte groeit dus niet met de grootte van gegevens in de tabel.

Geheugengebruik na het uitvoeren van de workload

Na het invoegen van 10 miljoen verkooporders ziet het geheugengebruik er ongeveer als volgt uit:

SELECT type,
       name,
       pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';

Hier is het resultatenoverzicht.

type name pages_MB
MEMORYCLERK_XTP Verstek 146
MEMORYCLERK_XTP DB_ID_5 7374
MEMORYCLERK_XTP Verstek 0
MEMORYCLERK_XTP Verstek 0

Zoals u ziet, gebruikt SQL Server iets minder dan 8 GB voor de tabellen en indexen die zijn geoptimaliseerd voor geheugen in de voorbeelddatabase.

Bekijk het gedetailleerde geheugengebruik per tabel na één voorbeelduitvoering:

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

Hier is het resultatenoverzicht.

Table name memory_allocated_for_table_kb memory_allocated_for_indexes_kb
SalesOrderDetail_inmem 5113761 663552
DemoSalesOrderDetailSeed 64 10368
SpecialOffer_inmem 2 8192
SalesOrderHeader_inmem 1575679 147456
Product_inmem 111 12032
SpecialOfferProduct_inmem 64 3712
** DemoSalesOrderHeaderSeed 1984 5504

We kunnen in totaal ongeveer 6,5 GB aan gegevens zien. De grootte van de indexen in de tabel SalesOrderHeader_inmem en SalesOrderDetail_inmem is gelijk aan de grootte van de indexen voordat u de verkooporders invoegt. De indexgrootte is niet gewijzigd omdat beide tabellen hash-indexen gebruiken en hash-indexen statisch zijn.

Na het opnieuw instellen van de demo

De opgeslagen procedure Demo.usp_DemoReset kan worden gebruikt om de demo opnieuw in te stellen. Hiermee worden de gegevens in de tabellen SalesOrderHeader_inmem en SalesOrderDetail_inmem verwijderd, en worden de gegevens opnieuw ingezaaid vanuit de oorspronkelijke tabellen SalesOrderHeader en SalesOrderDetail.

Hoewel de rijen in de tabellen zijn verwijderd, betekent dit niet dat er onmiddellijk geheugen wordt vrijgemaakt. SQL Server herwint op de achtergrond het geheugen van verwijderde rijen in voor geheugen geoptimaliseerde tabellen, indien nodig. U ziet dat het geheugen van verwijderde rijen na het opnieuw instellen van de demo, zonder transactionele werkbelasting op het systeem, nog niet is vrijgemaakt:

SELECT type,
       name,
       pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';

Hier is het resultatenoverzicht.

type name pages_MB
MEMORYCLERK_XTP Verstek 2261
MEMORYCLERK_XTP DB_ID_5 7396
MEMORYCLERK_XTP Verstek 0
MEMORYCLERK_XTP Verstek 0

Dit wordt verwacht: geheugen wordt vrijgemaakt wanneer de transactionele workload wordt uitgevoerd.

Als u een tweede uitvoering van de demoworkload start, ziet u dat het geheugengebruik in eerste instantie afneemt, omdat de eerder verwijderde rijen worden opgeschoond. Op een bepaald moment neemt de geheugengrootte opnieuw toe totdat de werkbelasting is voltooid. Na het invoegen van 10 miljoen rijen na het opnieuw instellen van de demo is het geheugengebruik erg vergelijkbaar met het gebruik na de eerste uitvoering. Bijvoorbeeld:

SELECT type,
       name,
       pages_kb / 1024 AS pages_MB
FROM sys.dm_os_memory_clerks
WHERE type LIKE '%xtp%';

Hier is het resultatenoverzicht.

type name pages_MB
MEMORYCLERK_XTP Verstek 1863
MEMORYCLERK_XTP DB_ID_5 7390
MEMORYCLERK_XTP Verstek 0
MEMORYCLERK_XTP Verstek 0

Schijfgebruik voor tabellen die zijn geoptimaliseerd voor geheugen

De totale grootte van de schijf voor de controlepuntbestanden van een database op een bepaald moment vindt u met behulp van de query:

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

Initiële status

Wanneer de voorbeeldbestandsgroep en voorbeeldtabellen die zijn geoptimaliseerd voor geheugen in eerste instantie worden gemaakt, worden er verschillende controlepuntbestanden vooraf gemaakt en wordt het systeem gestart met het vullen van de bestanden. Het aantal vooraf gemaakte controlepuntbestanden is afhankelijk van het aantal logische processors in het systeem. Omdat het voorbeeld in eerste instantie erg klein is, zijn de vooraf gemaakte bestanden meestal leeg na het maken.

De volgende code toont de oorspronkelijke grootte op schijf voor het voorbeeld op een computer met 16 logische processors:

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

Hier is het resultatenoverzicht.

Grootte op schijf in MB
2312

Zoals u kunt zien, is er een grote discrepantie tussen de grootte op de schijf van de controlepuntbestanden, namelijk 2,3 GB en de werkelijke gegevensgrootte, die dichter bij 30 MB ligt.

U kunt de volgende query gebruiken om te kijken waar het gebruik van de schijfruimte afkomstig is. De grootte op schijf die door deze query wordt geretourneerd, is bij benadering voor bestanden met de status 5 (VEREIST VOOR BACK-UP/HA), 6 (IN OVERGANG NAAR TOMBSTONE) of 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;

Voor de eerste status van het voorbeeld ziet het resultaat er ongeveer als volgt uit voor een server met 16 logische processors:

staatsbeschrijving bestandstypebeschrijving tellen Op schijf grootte MB
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF GEMAAKT DELTA 16 128
In Aanbouw GEGEVENS 1 128
In Aanbouw DELTA 1 8

Zoals u kunt zien, wordt de meeste ruimte gebruikt door vooraf gegenereerde gegevens- en deltabestanden. SQL Server heeft vooraf één paar (gegevens- en delta-bestanden) per logische processor aangemaakt. Bovendien worden gegevensbestanden vooraf ingesteld op 128 MB en deltabestanden op 8 MB, om het invoegen van gegevens in deze bestanden efficiënter te maken.

De werkelijke gegevens in de tabellen die zijn geoptimaliseerd voor geheugen, bevinden zich in het individuele gegevensbestand.

Na het uitvoeren van de workload

Na één testuitvoering die 10 miljoen verkooporders invoegt, ziet de totale grootte op de schijf er ongeveer als volgt uit (voor een testserver van 16 kernen):

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

Hier is het resultatenoverzicht.

Grootte op schijf in MB
8828

De grootte van de schijf ligt dicht bij 9 GB, wat dicht bij de grootte van de gegevens in het geheugen komt.

De grootte van de controlepuntbestanden in de verschillende statussen nader bekijken:

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;

Hier is het resultatenoverzicht.

state_desc file_type_desc count on-disk size MB
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF GEMAAKT DELTA 16 128
In Aanbouw GEGEVENS 1 128
In Aanbouw DELTA 1 8

We hebben nog steeds 16 voorgecreëerde bestandparen, klaar voor gebruik wanneer controlepunten worden afgesloten.

Er is één paar in aanbouw, dat wordt gebruikt totdat het huidige controlepunt is gesloten. Samen met de actieve controlepuntbestanden geeft dit ongeveer 6,5 GB aan schijfgebruik voor 6,5 GB aan gegevens in het geheugen. Zoals u weet, worden indexen niet op schijf bewaard en is de totale grootte op de schijf dus kleiner dan de grootte in het geheugen in dit geval.

Na het opnieuw instellen van de demo

Na het opnieuw instellen van de demo wordt schijfruimte niet onmiddellijk vrijgemaakt als er geen transactionele werkbelasting op het systeem is en er geen databasecontrolepunten zijn. Voor het verplaatsen van controlepuntbestanden door hun verschillende fasen tot aan hun uiteindelijke verwijdering, moeten er verschillende controlepunten en afkappingsgebeurtenissen voor logboeken plaatsvinden, om de samenvoeging van controlepuntbestanden en het starten van het opschoningsproces te initiëren. Deze gebeuren automatisch als u een transactionele workload in het systeem hebt (en regelmatige logboekback-ups maakt, voor het geval u het VOLLEDIGE herstelmodel gebruikt), maar niet wanneer het systeem niet actief is, zoals in een demoscenario.

In het voorbeeld ziet u na het opnieuw instellen van de demo iets als:

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

Hier is het resultatenoverzicht.

Grootte op schijf in MB
11839

Op bijna 12 GB is dit aanzienlijk meer dan de 9 GB die we hadden vóór de demo-reset. Dit komt doordat sommige controlepuntbestandssamenvoegingen zijn gestart, maar sommige van de samenvoegdoelen nog niet zijn geïnstalleerd en sommige van de samenvoegbronbestanden nog niet zijn opgeschoond, zoals te zien is in het volgende voorbeeld:

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;

Hier is het resultatenoverzicht.

state_desc file_type_desc count on-disk size MB
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF GEMAAKT DELTA 16 128
ACTIEF GEGEVENS 38 5152
ACTIEF DELTA 38 1331
SAMENVOEGDOEL GEGEVENS 7 896
SAMENVOEGDOEL DELTA 7 56
SAMENGEVOEGDE BRON GEGEVENS 13 1772
SAMENGEVOEGDE BRON DELTA 13 455

Samenvoegdoelen worden geïnstalleerd en de samengevoegde bron wordt opgeschoond wanneer er transactionele activiteit plaatsvindt in het systeem.

Na een tweede uitvoering van de demoworkload, waarbij 10 miljoen verkooporders zijn ingevoegd na de demo-reset, ziet u dat de bestanden die bij de eerste uitvoering van de workload zijn gemaakt, zijn opgeruimd. Als u de vorige query meerdere keren uitvoert terwijl de workload wordt uitgevoerd, kunt u zien dat de controlepuntbestanden de verschillende fasen doorlopen.

Na de tweede uitvoering van de werkbelasting, waarbij 10 miljoen verkooporders worden ingevoegd, is het schijfgebruik zeer vergelijkbaar met, maar niet noodzakelijkerwijs hetzelfde als na de eerste uitvoering, omdat het systeem van nature dynamisch is. Bijvoorbeeld:

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;

Hier is het resultatenoverzicht.

state_desc file_type_desc count on-disk size MB
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF GEMAAKT DELTA 16 128
In Aanbouw GEGEVENS 2 268
In Aanbouw DELTA 2 16
ACTIEF GEGEVENS 41 5608
ACTIEF DELTA 41 328

In dit geval zijn er twee controlepuntbestandsparen in de UNDER CONSTRUCTION status, wat betekent dat meerdere bestandsparen naar de UNDER CONSTRUCTION status zijn verplaatst, waarschijnlijk vanwege het hoge gelijktijdigheidsniveau in de workload. Voor meerdere gelijktijdige threads is tegelijkertijd een nieuw bestandspaar vereist en dus een paar verplaatst van PRECREATED naar UNDER CONSTRUCTION.