Delen via


Voorbeelddatabase voor In-Memory OLTP

van toepassing op:SQL ServerAzure SQL Database-

Overzicht

In dit voorbeeld ziet u de functie In-Memory OLTP. Het toont voor geheugen geoptimaliseerde tabellen en systeemeigen gecompileerde opgeslagen procedures en kan worden gebruikt om prestatievoordelen van In-Memory OLTP te demonstreren.

Notitie

Als u dit onderwerp voor SQL Server 2014 (12.x) wilt bekijken, raadpleegt u Extensies voor AdventureWorks om In-Memory OLTP-te demonstreren.

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 In-Memory OLTP 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 In-Memory OLTP: Hardwareoverwegingen voor In-Memory OLTP in SQL Server 2014

Het In-Memory OLTP-voorbeeld 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 uit SQLServer2016Samples.zip naar 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 hieronder wordt uitgelegd.

De nieuwe tabellen die zijn geoptimaliseerd voor geheugen bevatten 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

Voor het grootste deel 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. Hieronder worden de verschillen vermeld, 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 die verkooporders invoegt, met name als de systeemtijd moet worden opgehaald voor meerdere kolommen in de header van de verkooporder, evenals 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).

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

  • berekende kolommen: de berekende kolommen SalesOrderNumber en TotalDue worden weggelaten, omdat SQL Server 2016 (13.x) geen berekende kolommen in tabellen met geoptimaliseerd geheugen ondersteunt. 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) CTP 1.1.
      Vanaf SQL Server 2017 (14.x) CTP 1.1 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 veelgebruikte tabel in de voorbeeldworkload en beperkingen voor vreemde sleutels vereisen extra verwerking voor alle DML-bewerkingen, omdat er opzoekingen in alle andere tabellen nodig zijn waarnaar in deze beperkingen wordt 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 SalesOrderHeader, wordt de standaardbeperking waarvoor de systeemdatum/-tijd vereist, niet gemigreerd, in plaats daarvan zorgt de opgeslagen procedure voor het invoegen van verkooporders voor het invoegen van de huidige systeemdatum/-tijd bij de 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). Als u deze kolom wilt openen, gebruikt u de weergave Sales.vSalesOrderDetail_extended_inmem.

  • 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. Er moet echter rekening mee worden gehouden dat ze geen ondersteuning bieden voor bereikscans, geordende scans of zoekopdrachten op toonaangevende indexsleutelkolommen. Daarom moet u ervoor zorgen dat u deze indexen gebruikt. Daarnaast is het nodig om de bucket_count te specificeren bij het aanmaken. 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 voor 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): aantal buckets is 1 miljoen. De verstrekte gegevensset heeft niet veel klanten, maar dit zorgt voor toekomstige groei.

Sales.SalesOrderDetail_inmem heeft drie indexen, die allemaal HASH-indexen zijn vanwege prestatieredenen, en omdat er voor de workload geen geordende of bereikscans nodig zijn.

  • HASH-index op (SalesOrderID, SalesOrderDetailID): dit is de primaire sleutelindex, en hoewel zoekopdrachten op (SalesOrderID, SalesOrderDetailID) niet vaak voorkomen, 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): zoekacties per verkooporder zijn regelmatig: u wilt alle regelitems vinden die overeenkomen met één order. 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): aantal buckets is 1 miljoen. De verstrekte gegevensset heeft niet veel product, 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 worden uitgevoerd.

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

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 werkbelasting te optimaliseren: de indexen op (SpecialOfferID, ProductID) en (ProductID) zijn NIET GECLUSTERD.

Zoals u ziet, zijn sommige buckets in de bovenstaande buckets te groot, maar niet het aantal buckets voor de indexen op SalesOrderHeader_inmem en SalesOrderDetail_inmem: ze hebben een grootte van slechts 10 miljoen verkooporders. Dit is gedaan om het installeren van het voorbeeld op systemen met een lage geheugenbeschikbaarheid toe te staan, hoewel in die gevallen de demoworkload mislukt met onvoldoende geheugen. 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 zijn er details nodig voor de koptekst van de verkooporder, evenals de regelitems in de order.

    • Uitvoerparameter:

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

      • @DueDate datum/tijd2

      • @CustomerID int

      • @BillToAddressID [int]

      • @ShipToAddressID [int]

      • @ShipMethodID [int]

      • @SalesOrderDetails Sales.SalesOrderDetailType_inmem - tabelwaardeparameter (TVP) die de regelitems van de volgorde bevat

    • Invoerparameters (optioneel):

      • @Status [tinyint]

      • @OnlineOrderFlag [bit]

      • @PurchaseOrderNumber [nvarchar](25)

      • @AccountNumber [nvarchar](15)

      • @SalesPersonID [int]

      • @TerritoryID [int]

      • @CreditCardID [int]

      • @CreditCardApprovalCode [varchar](15)

      • @CurrencyRateID [int]

      • @Comment nvarchar(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 aangeroepen te worden vanuit de opgeslagen procedure van de wrapper 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 voor de integriteitsvalidatie van

    • 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 uit 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 wordt 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

Ostress uitvoeren

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 wordt weergegeven in de lijst met zoekresultaten.

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

De opdrachtregelopties voor ostress zijn zichtbaar wanneer u ostress.exe zonder opdrachtregelopties uitvoert. De belangrijkste opties die u kunt overwegen voor het uitvoeren van ostress met dit voorbeeld zijn:

  • -S-naam van het Microsoft SQL Server-exemplaar waarmee verbinding moet worden gemaakt

  • -E gebruikt Windows-verificatie om verbinding te maken (standaard); als u SQL Server-verificatie gebruikt, gebruikt u de opties -U en -P om respectievelijk de gebruikersnaam en het wachtwoord op te geven

  • -d naam van de database, voor dit voorbeeld AdventureWorks2022

  • -Q de T-SQL-instructie die moet worden uitgevoerd

  • -n aantal verbindingen dat elk invoerbestand/elke query verwerkt

  • -het aantal iteraties per verbinding om elk invoerbestand of iedere query uit te voeren

Demoworkload

De belangrijkste opgeslagen procedure die in de demoworkload wordt gebruikt, is Sales.usp_InsertSalesOrder_inmem/ondisk. In het onderstaande script wordt een tabelwaardeparameter (TVP) gemaakt met voorbeeldgegevens en wordt de procedure aangeroepen om een verkooporder met vijf regelposten in te voegen.

Het ostress-tool wordt gebruikt om opgeslagen procedureaanroepen parallel uit te voeren voor het simuleren van klanten die tegelijkertijd verkooporders invoegen.

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 int = 0,   
      @od Sales.SalesOrderDetailType_inmem,   
      @SalesOrderID int,   
      @DueDate datetime2 = sysdatetime(),   
      @CustomerID int = rand() * 8000,   
      @BillToAddressID int = rand() * 10000,   
      @ShipToAddressID int = rand() * 10000,   
      @ShipMethodID 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;   
      EXEC 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 zal de middellaagtoepassing de verkooporder samenstellen die moet worden ingediend.

Met het bovenstaande 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 exemplaren 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 op elke verbinding wordt uitgevoerd.

De werklast 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, kijk bij de sectie Oplossen van problemen met traag uitgevoerde tests. Als u het stressniveau voor deze test wilt verminderen, verlaagt u het aantal verbindingen door de parameter '-n' te wijzigen. Als u bijvoorbeeld het aantal verbindingen wilt verlagen naar 40, wijzigt u de parameter '-n100' in '-n40'.

Als prestatiemeting voor de workload gebruiken we de verstreken tijd zoals gerapporteerd door ostress.exe na het uitvoeren van de workload.

De onderstaande instructies en metingen gebruiken een workload waarmee 10 miljoen verkooporders worden ingevoegd. Zie de instructies in 'In-Memory OLTP\readme.txt' that is part of the SQLServer2016Samples.zip archief' voor instructies voor het uitvoeren van een uitgeschaalde workload die 1 miljoen verkooporders invoegt.

Tabellen die zijn geoptimaliseerd voor geheugen

We beginnen met het uitvoeren van de workload voor 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 int = 0, @od Sales.SalesOrderDetailType_inmem, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID 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; EXEC 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, hebt u een log-IO-knelpunt. Zie ook Problemen met het oplossen van traag uitgevoerde tests.

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. De tabel die is geoptimaliseerd voor geheugen, is vergrendelingsvrij en lijdt dus niet aan 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 int = 0, @od Sales.SalesOrderDetailType_ondisk, @SalesOrderID int, @DueDate datetime2 = sysdatetime(), @CustomerID int = rand() * 8000, @BillToAddressID int = rand() * 10000, @ShipToAddressID int = rand() * 10000, @ShipMethodID 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; EXEC 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 het feit dat SQL Server bij het gebruik van tabellen op basis van schijven niet volledig gebruik kan maken van de CPU. 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. Je zult zien dat met schijftabellen het CPU-gebruik 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 workload alleen invoegt, verbruikt elke uitvoering meer geheugen en is er dus een reset vereist om te voorkomen dat er onvoldoende geheugen beschikbaar is. De hoeveelheid geheugen die na een uitvoering wordt verbruikt, wordt besproken in sectie geheugengebruik na het uitvoeren van de workload.

Problemen met trage tests oplossen

Testresultaten variëren doorgaans met hardware en ook het gelijktijdigheidsniveau 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 in het systeem is, omdat er slechts zoveel gelijktijdige uitvoeringen van transacties kunnen zijn als er kernen beschikbaar zijn voor SQL.

    • Symptoom: als het CPU-gebruik hoog is bij het uitvoeren van de workload op schijfgebaseerde tabellen, betekent dit dat er niet veel conflicten optreden, wat wijst op ontbrekende gelijktijdigheid.
  • Snelheid van het logboekstation: Als het logboekstation het niveau van transactiedoorvoer in het systeem niet kan bijhouden, wordt de workload een knelpunt bij logboek-IO. 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 fluctuerend is bij het draaien van de workload op geheugen-geoptimaliseerde tabellen, is het mogelijk dat er sprake is van een log-IO-knelpunt. 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 onderstaande beschrijven we wat u kunt verwachten in termen van geheugen- en schijfruimtegebruik voor de voorbeelddatabase. We tonen ook de resultaten die we hebben gezien op 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 systeem), 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 dms JOIN sys.tables 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 geheugen_toegewezen_aan_tabel_kb geheugen_toegewezen_voor_indexen_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 is en SalesOrderDetail_inmem ongeveer 15 MB groot is.

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 vooraf zijn aangepast voor een grotere gegevensgrootte. Houd er rekening mee dat hash-indexen een vaste grootte hebben en dat de grootte ervan niet groter wordt 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%'  
type naam 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 dms JOIN sys.tables t   
ON dms.object_id=t.object_id  
WHERE t.type='U'  
Tabelnaam geheugen_toegewezen_voor_tabel_kb geheugen_toegewezen_voor_indexen_kb
SalesOrderDetail_inmem 5113761 663552
Demo Verkooporder Detail Zaad 64 10368
SpecialeAanbieding_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. U ziet dat de grootte van de indexen in de tabel SalesOrderHeader_inmem en SalesOrderDetail_inmem gelijk is 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_inmemverwijderd en worden de gegevens opnieuw ingevoerd uit 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 zult zien 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%';
type naam 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%';
type naam 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 f JOIN sys.database_files 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 vooraf een aantal controlepuntbestanden 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 f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';  
Grootte op schijf in MB
2312

Zoals u kunt zien, is er een grote discrepantie tussen de schijfgrootte van de controlepuntbestanden, die 2,3 GB is 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 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-, delta)-bestanden per logische processor gemaakt. Daarnaast 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 f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';  
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;
state_desc file_type_desc tellen op-schijf grootte MB
VOORAF GECREËERD GEGEVENS 16 2048
VOORAF GEMAAKT DELTA 16 128
In aanbouw GEGEVENS 1 128
IN AANBOUW DELTA 1 8

We hebben nog steeds 16 paren voorgecreëerde bestanden, klaar voor gebruik zodra de controlepunten worden gesloten.

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 workload op het systeem is en er geen databasecontrolepunten zijn. Voor het verwerken van controlepuntbestanden door hun verschillende fasen en uiteindelijk te worden verwijderd, moeten een aantal controlepunten en logafkappingsgebeurtenissen plaatsvinden, om de samenvoeging van controlepuntbestanden te initiëren en om vuilnisopruiming te initiëren. Dit gebeurt 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 inactief is, zoals in een demoscenario.

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

SELECT SUM(df.size) * 8 / 1024 AS [On-disk size in MB]  
FROM sys.filegroups f JOIN sys.database_files df   
   ON f.data_space_id=df.data_space_id  
WHERE f.type=N'FX';
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 u kunt zien in het volgende:

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;
state_desc bestandstypebeschrijving tellen grootte MB op schijf
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF AANGEMAAKT 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 worden ingevoegd na het opnieuw instellen van de demo, ziet u dat de bestanden die tijdens de eerste uitvoering van de workload zijn gemaakt, zijn opgeschoond. Als u de bovenstaande 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 workload, wanneer 10 miljoen verkooporders worden ingevoegd, zal het schijfgebruik zeer vergelijkbaar zijn met, maar niet per se 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;
status_omschrijving bestandstype_beschrijving tellen Op schijf grootte MB
VOORAF GEMAAKT GEGEVENS 16 2048
VOORAF AANGEMAAKT 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 status 'under construction', wat betekent dat meerdere bestandsparen zijn verplaatst naar de status 'under construction', waarschijnlijk vanwege het hoge gelijktijdigheidsniveau in de workload. Meerdere gelijktijdige threads vereisten tegelijkertijd een nieuw bestandspaar en verplaatste daarom een paar van 'vooraf gecreëerd' naar 'in aanbouw'.

Volgende stappen