Delen via


Enquête over eerste gebieden in In-Memory OLTP

van toepassing op:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Dit artikel is bedoeld voor de ontwikkelaar die haast heeft om de basisprincipes van de In-Memory OLTP-prestatiefuncties van Microsoft SQL Server en Azure SQL Database te leren.

Voor In-Memory OLTP biedt dit artikel het volgende:

  • Snelle uitleg van de functies.
  • Kerncodevoorbeelden waarmee de functies worden geïmplementeerd.

SQL Server en SQL Database hebben slechts kleine variaties in de ondersteuning van In-Memory technologieën.

In de praktijk verwijzen sommige bloggers naar de In-Memory OLTP als Hekaton.

Voordelen van In-Memory-functies

SQL Server biedt In-Memory functies die de prestaties van veel toepassingssystemen aanzienlijk kunnen verbeteren. De meest eenvoudige overwegingen worden beschreven in deze sectie.

Functies voor OLTP (online transactionele verwerking)

Systemen die grote aantallen SQL INSERT's gelijktijdig moeten verwerken, zijn uitstekende kandidaten voor de OLTP-functies.

  • Onze benchmarks laten zien dat snelheidsverbeteringen van 5 keer tot 20 keer sneller haalbaar zijn door de acceptatie van de In-Memory functies.

Systemen die zware berekeningen verwerken in Transact-SQL zijn uitstekende kandidaten.

  • Een opgeslagen procedure die is toegewezen aan zware berekeningen, kan tot 99 keer sneller worden uitgevoerd.

Later kunt u de volgende artikelen bezoeken die demonstraties van prestatieverbeteringen van In-Memory OLTP bieden:

Functies voor Operational Analytics

In-Memory Analytics verwijst naar SQL SELECTs die transactionele gegevens aggregeren, meestal door een GROUP BY-component op te nemen. Het indextype columnstore is centraal in operationele analyses.

Er zijn twee belangrijke scenario's:

  • Batch Operational Analytics- verwijst naar aggregatieprocessen die worden uitgevoerd na kantooruren of op secundaire hardware met kopieën van de transactionele gegevens.
  • Realtime Operational Analytics- verwijst naar aggregatieprocessen die worden uitgevoerd tijdens kantooruren en op de primaire hardware die wordt gebruikt voor transactionele workloads.

Het huidige artikel richt zich op OLTP en niet op Analytics. Zie voor meer informatie over hoe columnstore-indexen Analytics naar SQL brengen:

Columnstore

In een reeks uitstekende blogposts worden columnstore-indexen vanuit verschillende perspectieven elegant uitgelegd. De meeste berichten beschrijven verder het concept van realtime operationele analyses, die columnstore ondersteunt. Deze berichten zijn geschreven door Sunil Agarwal, een Program Manager bij Microsoft, in maart 2016.

Reële tijd Operationele Analyse

  1. Real-Time Operationele Analytics met behulp van In-Memory Technologie
  2. Real-Time Operational Analytics - Overzicht van niet-geclusterde columnstore-index (NCCI)
  3. Real-Time Operational Analytics: Eenvoudig voorbeeld met een niet-geclusterde columnstore-index (NCCI) in SQL Server 2016
  4. Real-Time Operational Analytics: DML-bewerkingen en niet-geclusterde columnstore-index (NCCI) in SQL Server 2016
  5. Real-Time Operational Analytics: gefilterde niet-geclusterde columnstore-index (NCCI)
  6. Real-Time Operational Analytics: Optie voor compressievertraging voor niet-geclusterde columnstore-index (NCCI)
  7. Real-Time Operational Analytics: de optie Compressievertraging met NCCI en de bijbehorende prestaties
  8. Real-Time Operationele Analytics: Memory-Optimized Tabellen en Columnstore-index

Een columnstore-index defragmenteren

  1. Columnstore-index defragmentatie met behulp van de opdracht REORGANIZE
  2. Columnstore-index samenvoegen voor het opnieuw organiseren van

Bulkimport van gegevens

  1. gegroepeerd kolomarchief: bulksgewijs laden
  2. Geclusterde kolomopslagindex: Optimalisaties van gegevensladen - Minimale logregistratie
  3. Geclusterde columnstore-index: Optimalisatie van gegevensinvoer - Parallelle bulkimport

Functies van In-Memory OLTP

Laten we eens kijken naar de belangrijkste functies van In-Memory OLTP.

Tabellen die zijn geoptimaliseerd voor geheugen

Het T-SQL-trefwoord MEMORY_OPTIMIZED, in de instructie CREATE TABLE, is hoe een tabel wordt gemaakt om te bestaan in het actieve geheugen, in plaats van op schijf.

Een geheugen-geoptimaliseerde tabel heeft één weergave van zichzelf in het actieve geheugen en een secundaire kopie op de schijf.

  • De schijfkopie is voor routineherstel na het afsluiten en vervolgens opnieuw opstarten van de server of database. Deze dualiteit met geheugen plus schijven is volledig verborgen voor u en uw code.

Systeemeigen gecompileerde modules

Het T-SQL-trefwoord NATIVE_COMPILATION, in de instructie CREATE PROCEDURE, is hoe een systeemeigen gecompileerde opgeslagen procedure wordt gemaakt. De T-SQL-instructies worden gecompileerd naar machinecode bij het eerste gebruik van de systeemeigen proc telkens wanneer de database online wordt gecyclusd. De T-SQL-instructies verdragen geen langzame interpretatie van elke instructie meer.

  • We hebben systeemeigen compilatieresultaten gezien in duur die 1/100e van de geïnterpreteerde duur zijn.

Een systeemeigen module kan alleen verwijzen naar tabellen die zijn geoptimaliseerd voor geheugen en kan niet verwijzen naar tabellen op basis van schijven.

Er zijn drie typen systeemeigen gecompileerde modules:

Beschikbaarheid in Azure SQL Database

In-Memory OLTP en Columnstore zijn beschikbaar in Azure SQL Database. Zie Prestaties optimaliseren met behulp van In-Memory Technologies in SQL Databasevoor meer informatie.

1. Zorg ervoor dat het compatibiliteitsniveau >= 130

Deze sectie begint een reeks genummerde secties die samen de Transact-SQL syntaxis laten zien die u kunt gebruiken om In-Memory OLTP-functies te implementeren.

Ten eerste is het belangrijk dat uw database wordt ingesteld op een compatibiliteitsniveau van ten minste 130. Hierna volgt de T-SQL-code om het huidige compatibiliteitsniveau weer te geven waarop uw huidige database is ingesteld.

SELECT d.compatibility_level
    FROM sys.databases as d
    WHERE d.name = Db_Name();

Hierna volgt de T-SQL-code om het niveau bij te werken, indien nodig.

ALTER DATABASE CURRENT
    SET COMPATIBILITY_LEVEL = 130;

2. Upgraden naar Momentopname

Wanneer een transactie zowel een tabel op basis van schijf als een tabel met geoptimaliseerd geheugen omvat, noemen we dat een transactie tussen containers. In een dergelijke transactie is het essentieel dat het voor geheugen geoptimaliseerde gedeelte van de transactie werkt op het niveau van transactieisolatie met de naam SNAPSHOT.

Als u dit niveau op betrouwbare wijze wilt afdwingen voor geheugen-geoptimaliseerde tabellen in een transactie tussen containers, wijzig de database-instelling door het uitvoeren van de volgende T-SQL.

ALTER DATABASE CURRENT
    SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON;

3. Een geoptimaliseerde FILEGROUP maken

Voordat u in Microsoft SQL Server een tabel kunt maken die is geoptimaliseerd voor geheugen, moet u eerst een FILEGROUP maken die u CONTAINS-MEMORY_OPTIMIZED_DATA declareert. De FILEGROUP is toegewezen aan uw database. Zie voor meer informatie:

In Azure SQL Database hebt u een dergelijke FILEGROUP niet nodig en kunt u deze niet maken.

Met het volgende T-SQL-voorbeeldscript wordt een database voor In-Memory OLTP ingeschakeld en worden alle aanbevolen instellingen geconfigureerd. Het werkt met zowel SQL Server als Azure SQL Database: enable-in-memory-oltp.sql.

Houd er rekening mee dat niet alle SQL Server-functies worden ondersteund voor databases met een MEMORY_OPTIMIZED_DATA-bestandsgroep. Zie voor meer informatie over beperkingen: Niet-ondersteunde SQL Server-functies voor In-Memory OLTP-

4. Een tabel maken die is geoptimaliseerd voor geheugen

Het cruciale Transact-SQL trefwoord is het trefwoord MEMORY_OPTIMIZED.

CREATE TABLE dbo.SalesOrder
    (
        SalesOrderId   integer   not null   IDENTITY
            PRIMARY KEY NONCLUSTERED,
        CustomerId   integer    not null,
        OrderDate    datetime   not null
    )
        WITH
            (MEMORY_OPTIMIZED = ON,
            DURABILITY = SCHEMA_AND_DATA);

Transact-SQL INSERT- en SELECT-instructies voor een tabel die is geoptimaliseerd voor geheugen, zijn hetzelfde als voor een normale tabel.

ALTER TABLE voor Memory-Optimized tabellen

ALTER TABLE... MET ADD/DROP kunt u een kolom toevoegen aan of verwijderen uit een tabel die is geoptimaliseerd voor geheugen of een index.

  • CREATE INDEX en DROP INDEX kunnen niet worden uitgevoerd voor een geheugen-geoptimaliseerde tabel, gebruik in plaats daarvan ALTER TABLE ... ADD/DROP INDEX.
  • Zie Memory-Optimized tabellen wijzigenvoor meer informatie.

Uw voor geheugen geoptimaliseerde tabellen en indexen plannen

5. Maak een systeemeigen gecompileerde opgeslagen procedure (systeemeigen proc)

Het cruciale trefwoord is NATIVE_COMPILATION.

CREATE PROCEDURE ncspRetrieveLatestSalesOrderIdForCustomerId  
        @_CustomerId   INT  
        WITH  
            NATIVE_COMPILATION,  
            SCHEMABINDING  
    AS  
    BEGIN ATOMIC  
        WITH  
            (TRANSACTION ISOLATION LEVEL = SNAPSHOT,
            LANGUAGE = N'us_english')  
      
        DECLARE @SalesOrderId int, @OrderDate datetime;
      
        SELECT TOP 1  
                @SalesOrderId = s.SalesOrderId,  
                @OrderDate    = s.OrderDate  
            FROM dbo.SalesOrder AS s  
            WHERE s.CustomerId = @_CustomerId  
            ORDER BY s.OrderDate DESC;  
      
        RETURN @SalesOrderId;  
    END;  

Het trefwoord SCHEMABINDING betekent dat de tabellen waarnaar wordt verwezen in de systeemeigen proc niet kunnen worden verwijderd, tenzij de systeemeigen proc eerst wordt verwijderd. Zie voor meer informatie Het maken van systeemeigen gecompileerde opgeslagen procedures.

Houd er rekening mee dat u geen systeemeigen gecompileerde opgeslagen procedure hoeft te maken voor toegang tot een tabel die is geoptimaliseerd voor geheugen. U kunt ook verwijzen naar geheugen-geoptimaliseerde tabellen vanuit traditionele opgeslagen procedures en ad-hoc batches.

6. Voer de systeemeigen proc uit

Vul de tabel met twee rijen met gegevens.

INSERT into dbo.SalesOrder  
        ( CustomerId, OrderDate )  
    VALUES  
        ( 42, '2013-01-13 03:35:59' ),
        ( 42, '2015-01-15 15:35:59' );

Een EXECUTE-aanroep naar de systeemeigen gecompileerde opgeslagen procedure volgt.

DECLARE @LatestSalesOrderId int, @mesg nvarchar(128);
      
EXECUTE @LatestSalesOrderId =  
    ncspRetrieveLatestSalesOrderIdForCustomerId 42;
      
SET @mesg = CONCAT(@LatestSalesOrderId,  
    ' = Latest SalesOrderId, for CustomerId = ', 42);
PRINT @mesg;  

Dit is de werkelijke PRINT-uitvoer:

-- 2 = Latest SalesOrderId, for CustomerId = 42  

Handleiding voor de documentatie en de volgende stappen

De voorgaande eenvoudige voorbeelden geven u een basis voor het leren van de meer geavanceerde functies van In-Memory OLTP. De volgende secties zijn een handleiding voor de speciale overwegingen die u mogelijk moet weten en waar u de details over elk ervan kunt zien.

Hoe In-Memory OLTP-functies zo veel sneller werken

In de volgende subsecties wordt kort beschreven hoe de In-Memory OLTP-functies intern werken om betere prestaties te bieden.

Hoe tabellen die zijn geoptimaliseerd voor geheugen sneller presteren

Dual nature: Een tabel die is geoptimaliseerd voor geheugen heeft een dubbele aard: één weergave in het actieve geheugen en de andere op de harde schijf. Elke transactie wordt doorgevoerd in beide representaties van de tabel. Transacties werken op basis van de veel snellere actieve geheugenweergave. Tabellen die zijn geoptimaliseerd voor geheugen, profiteren van de grotere snelheid van het actieve geheugen ten opzichte van de schijf. Bovendien maakt de grotere behendigheid van actief geheugen praktischer een geavanceerdere tabelstructuur die is geoptimaliseerd voor snelheid. De geavanceerde structuur is ook paginaloos, dus het voorkomt de overhead en wedijver van sloten en spinlocks.

Geen vergrendelingen: De tabel die is geoptimaliseerd voor geheugen, is afhankelijk van een optimistische benadering van de concurrerende doelstellingen van gegevensintegriteit versus gelijktijdigheid en hoge doorvoer. Tijdens de transactie plaatst de tabel geen vergrendelingen op een versie van de bijgewerkte rijen met gegevens. Dit kan conflicten in sommige systemen met grote volumes aanzienlijk verminderen.

rijversies: In plaats van vergrendelingen voegt de tabel die is geoptimaliseerd voor geheugen een nieuwe versie van een bijgewerkte rij toe in de tabel zelf, niet in tempdb. De oorspronkelijke rij wordt bewaard totdat de transactie is doorgevoerd. Tijdens de transactie kunnen andere processen de oorspronkelijke versie van de rij lezen.

  • Wanneer er meerdere versies van een rij worden gemaakt voor een tabel op basis van een schijf, worden rijversies tijdelijk opgeslagen in tempdb.

Minder logboekregistratie: De voor- en naversies van de bijgewerkte rijen worden bewaard in de tabel geoptimaliseerd voor geheugen. Het paar rijen bevat veel van de informatie die traditioneel naar het logboekbestand wordt geschreven. Hierdoor kan het systeem minder informatie en minder vaak naar het logboek schrijven. Maar transactionele integriteit wordt gegarandeerd.

Hoe systeemeigen procs sneller presteren

Het converteren van een reguliere geïnterpreteerde opgeslagen procedure naar een systeemeigen gecompileerde opgeslagen procedure vermindert het aantal instructies dat moet worden uitgevoerd tijdens de runtime aanzienlijk.

Afwegingen van In-Memory functies

Zoals gebruikelijk in computerwetenschap, zijn de prestatieverbeteringen die de In-Memory functies bieden een compromis. De betere functies bieden voordelen die waardevoller zijn dan de extra kosten van de functie. U vindt uitgebreide richtlijnen over de afwegingen op:

In de rest van deze sectie vindt u enkele belangrijke overwegingen voor planning en afwegingen.

Afwegingen van geheugen-geoptimaliseerde tabellen

Geheugengebruik schatten: U moet de hoeveelheid actief geheugen schatten die uw geheugen-geoptimaliseerde tabel zal gebruiken. Uw computersysteem moet voldoende geheugencapaciteit hebben om een tabel te hosten die is geoptimaliseerd voor geheugen. Zie voor meer informatie:

Partitioneer uw grote tabel: Een manier om te voldoen aan de vraag naar veel actief geheugen, is door uw grote tabel te partitioneren in onderdelen in het geheugen waarin recente gegevensrijen worden opgeslagen versus andere delen op de schijf waarin koude verouderde rijen (zoals verkooporders die volledig zijn verzonden en voltooid) worden opgeslagen. Deze partitionering is een handmatig proces van ontwerp en implementatie. Zien:

Afwegingen van systeemeigen processen

  • Een systeemeigen gecompileerde opgeslagen procedure heeft geen toegang tot een tabel op basis van een schijf. Een systeemeigen proc heeft alleen toegang tot tabellen die zijn geoptimaliseerd voor geheugen.
  • Wanneer een systeemeigen proc voor het eerst wordt uitgevoerd nadat de server of database het laatst weer online is gebracht, moet de systeemeigen proc eenmalig opnieuw worden gecompileerd. Dit veroorzaakt een vertraging voordat de systeemeigen proc wordt uitgevoerd.

Geavanceerde overwegingen voor tabellen die zijn geoptimaliseerd voor geheugen

indexen voor Memory-Optimized tabellen verschillen op een aantal manieren van indexen in traditionele tabellen op schijf. Hash-indexen zijn alleen beschikbaar voor tabellen die zijn geoptimaliseerd voor geheugen.

U moet plannen om ervoor te zorgen dat er voldoende geheugen is voor uw geplande geheugen-geoptimaliseerde tabel en de bijbehorende indexen. Zien:

Een tabel die is geoptimaliseerd voor geheugen kan worden gedeclareerd met DUURZAAMHEID = SCHEMA_ONLY:

  • Deze syntaxis geeft aan dat het systeem alle gegevens uit de tabel die is geoptimaliseerd voor geheugen, moet verwijderen wanneer de database offline wordt gehaald. Alleen de tabeldefinitie blijft behouden.
  • Wanneer de database weer online wordt gebracht, wordt de tabel die is geoptimaliseerd voor geheugen, weer in het actieve geheugen geladen, leeg met gegevens.
  • SCHEMA_ONLY tabellen kunnen een superieure alternatief zijn voor #temporary tabellen in tempdb, wanneer er veel duizenden rijen bij betrokken zijn.

Tabelvariabelen kunnen ook worden gedeclareerd als geoptimaliseerd voor geheugen. Zien:

Geavanceerde overwegingen voor systeemeigen gecompileerde modules

De typen systeemeigen gecompileerde modules die beschikbaar zijn via Transact-SQL zijn:

Een systeemeigen gecompileerde door de gebruiker gedefinieerde functie (UDF) wordt sneller uitgevoerd dan een geïnterpreteerde UDF. Hier volgen enkele aandachtspunten voor UDF's:

  • Wanneer een T-SQL SELECT een UDF gebruikt, wordt de UDF altijd één keer per geretourneerde rij aangeroepen.
    • UDF's worden nooit inline uitgevoerd en worden in plaats daarvan altijd aangeroepen.
    • Het gecompileerde onderscheid is minder belangrijk dan de overhead van herhaalde aanroepen die inherent zijn aan alle UDF's.
    • Toch is de overhead van UDF-aanroepen vaak aanvaardbaar op praktisch niveau.

Zie voor testgegevens en uitleg over de prestaties van systeemeigen UDF's:

Documentatiehandleiding voor tabellen die zijn geoptimaliseerd voor geheugen

Raadpleeg deze andere artikelen met speciale overwegingen voor tabellen die zijn geoptimaliseerd voor geheugen:

Documentatiehandleiding voor systeemeigen procs

In het volgende artikel en de onderliggende artikelen in de inhoudsopgave (INHOUDSopgave) worden de details uitgelegd over systeemeigen opgeslagen procedures.

Hier volgen artikelen die code bieden om de prestatieverbeteringen te laten zien die u kunt bereiken met behulp van In-Memory OLTP: