Überblick des Anfangsbereichs in In-Memory OLTP

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

Dieser Artikel ist für Entwickler konzipiert, die schnell die Grundlagen der In-Memory-OLTP-Leistungsmerkmale von Microsoft SQL Server und der Azure SQL-Datenbank lernen möchten.

Dieser Artikel bietet für In-Memory-OLTP Folgendes:

  • Eine kurze Erklärung der Funktionen
  • Core-Codebeispiele, die die Funktionen implementieren

SQL Server und die SQL-Datenbank haben nur geringfügige Unterschiede bei ihrer Unterstützung der In-Memory-Technologien.

In der Praxis verwenden Blogger für die In-Memory-OLTP-Funktionen auch den Begriff Hekaton.

Vorteile der In-Memory-Funktionen

SQL Server bietet In-Memory-Funktionen, die die Leistung von vielen Anwendungssystemen erheblich verbessern können. In diesem Abschnitt werden die häufigsten unkomplizierten Aspekte beschrieben.

Funktionen für OLTP (Online Transactional Processing – Onlinetransaktionsverarbeitung)

Systeme, die eine große Anzahl von SQL INSERTs gleichzeitig verarbeiten müssen, sind hervorragende Kandidaten für die OLTP-Features.

  • Unsere Vergleichtests zeigen, dass Verbesserungen der Geschwindigkeit um das 5- bis 20-fache möglich sind, wenn die In-Memory-Funktionen angewendet werden.

Systeme, die hohe Berechnungen in Transact-SQL ausführen, sind eine ausgezeichnete Wahl.

  • Eine gespeicherte Prozedur, die für hohe Berechnungen vorgesehen ist, kann bis zu 99-mal schneller ausgeführt werden.

Sie können sich später die folgenden Artikel ansehen, die Demonstrationen der Leistungsgewinne durch In-Memory-OLTP bieten:

Funktionen für die operative Analyse

In-Memory-Analyse bezieht sich auf SQL SELECT-Anweisungen, die in der Regel Transaktionsdaten durch Inklusion einer GROUP BY-Klausel aggregieren. Der Indextyp heißt columnstore und ist ein wesentlicher Bestandteil der operativen Analyse.

Es gibt zwei wichtige Szenarios:

  • Operative Analyseprozesse im Batchmodus verweist auf Aggregationsprozesse, die entweder nach den Geschäftsstunden ausgeführt werden oder auf sekundärer Hardware, die über Kopien der Transaktionsdaten verfügt.
  • Operative Echtzeitanalyse verweist auf Aggregationsprozesse, die entweder während der Geschäftsstunden ausgeführt werden oder auf der primären Hardware, die für Transaktionsarbeitsauslastung verwendet wird.

Dieser Artikel fokussiert sich auf OLTP und nicht auf Analyseaufgaben. Informationen darüber, wie Columnstore-Indizes Analytics auf SQL überträgt, finden Sie unter:

columnstore

Eine Reihe exzellenter Blogbeiträge erklärt Ihnen aus verschiedenen Blickwinkeln Columnstore-Indizes auf leicht verständliche Art und Weise. In den meisten dieser Beiträge wird auch das von Columnstore unterstützte Konzept der operativen Echtzeitanalyse genauer beschrieben. Diese Beiträge wurden im März 2016 von Sunil Agarwal, Program Manager bei Microsoft, verfasst.

Operative Echtzeitanalyse

  1. Real-Time Operational Analytics Using In-Memory Technology (Operative Echtzeitanalyse mit In-Memory-Technologie)
  2. Real-Time Operational Analytics – Overview nonclustered columnstore index (NCCI) (Operative Echtzeitanalyse: Überblick über den nicht gruppierten Columnstore-Index [Nonclustered Columnstore Index, NCCI])
  3. Real-Time Operational Analytics: Simple example using nonclustered clustered columnstore index (NCCI) in SQL Server 2016 (Operative Echtzeitanalyse: Einfaches Beispiel mit Verwendung des gruppierten/nicht gruppierten Columnstore-Index [Nonclustered Columnstore Index, NCCI] in SQL Server 2016)
  4. Real-Time Operational Analytics: DML operations and nonclustered columnstore index (NCCI) in SQL Server 2016 (Operative Echtzeitanalyse: DML-Operationen und nicht gruppierter Columnstore-Index [Nonclustered Columnstore Index, NCCI] in SQL Server 2016)
  5. Real-Time Operational Analytics: Filtered nonclustered columnstore index (NCCI) (Operative Echtzeitanalyse: Gefilterter, nicht gruppierter Columnstore-Index [Nonclustered Columnstore Index, NCCI])
  6. Echtzeit-Betriebsanalyse: Komprimierungsverzögerungsoption für nicht gruppierten Columnstore-Index (NCCI)
  7. Real-Time Operational Analytics: Compression Delay option with NCCI and the performance (Operative Echtzeitanalyse: Performance des nicht gruppierten Columnstore-Index [Nonclustered Columnstore Index, NCCI] mit aktivierter Option „Kompressionsverzögerung“)
  8. Echtzeit-Betriebsanalyse: Speicheroptimierte Tabellen und Spaltenspeicherindex

Defragmentieren eines Columnstore-Index

  1. Columnstore index Defragmentation using REORGANIZE Command (Defragmentieren des Columnstore-Index mithilfe des Befehls REORGANIZE)
  2. Columnstore index Merge Policy for REORGANIZE (Zusammenführungsrichtlinie für REORGANIZE des Columnstore-Index)

Ausführen eines Massenimports von Daten

  1. Clustered Column Store: Bulk Load (Gruppierter Columnstore-Index: Massenladen)
  2. Clustered columnstore index: Data Load Optimizations - Minimale Protokollierung
  3. Gruppierter Spaltenspeicherindex: Datenladeoptimierung - Paralleler Massenimport

Funktionen von In-Memory-OLTP

Betrachten wir nun die wichtigsten Funktionen von In-Memory-OLTP.

Speicheroptimierte Tabellen

Das T-SQL-Schlüsselwort MEMORY_OPTIMIZED in der CREATE TABLE-Anweisung zeigt wie eine Tabelle erstellt wird, um im aktiven Arbeitsspeicher zu existieren, anstatt auf dem Datenträger.

Eine speicheroptimierte Tabelle hat eine Darstellung von sich selbst im aktiven Arbeitsspeicher und eine sekundäre Kopie auf dem Datenträger.

  • Die Kopie auf dem Datenträger ist für die routinemäßige Wiederherstellung nach einem Herunterfahren und anschließendem Neustart des Servers oder der Datenbank. Diese In-Memory-plus-Datenträger-Dualität ist vollständig unsichtbar für Sie und Ihren Code.

Nativ kompilierte Module

Das T-SQL-Schlüsselwort NATIVE_COMPILATION in der CREATE PROCEDURE-Anweisung zeigt, wie eine nativ kompilierte gespeicherte Prozedur erstellt wird. Die T-SQL-Anweisungen werden jedes Mal bei der ersten Verwendung der nativen Prozedur in Computercode kompiliert, wenn die Datenbank erneut online gestellt wird. Die T-SQL-Anweisungen erdulden nicht länger das langsame Interpretieren jeder Anweisung.

  • Es kann vorkommen, dass diese Kompilierung (nativ) nur 1 % der Zeit benötigt, die für eine interpretierte gespeicherte Prozedur benötigt wird.

Ein natives Modul kann nur speicheroptimierte Tabellen verweisen. Sie kann keine datenträgerbasierten Tabellen verweisen.

Es gibt drei Arten von nativ kompilierten Modulen:

Verfügbarkeit in Azure SQL-Datenbank

In-Memory-OLTP und Columnstore sind in Azure SQL-Datenbank verfügbar. Weitere Informationen finden Sie unter Optimieren der Leistung mithilfe von In-Memory-Technologien in SQL-Datenbank.

1. Sicherstellen der Kompatibilitätsstufe >= 130

Dieser Abschnitt beginnt mit einer Sequenz von nummerierten Abschnitten, die zusammen die Transact-SQL-Syntax veranschaulicht, die Sie verwenden können, um In-Memory-OLTP-Funktionen zu implementieren.

Zuerst ist es wichtig, dass Ihre Datenbank auf einen Kompatibilitätsgrad von mindestens 130 festgelegt ist. Als Nächstes wird der T-SQL-Code verwendet, um den aktuellen Kompatibilitätsgrad anzuzeigen, auf den Ihre aktuelle Datenbank festgelegt ist.

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

Danach wird der T-SQL-Code verwendet, um den Grad wenn nötig zu aktualisieren.

ALTER DATABASE CURRENT
    SET COMPATIBILITY_LEVEL = 130;

2. Erhöhen auf Momentaufnahme

Wenn eine Transaktion jeweils eine datenträgerbasierte Tabelle und eine speicheroptimierte Tabelle einschließt, nennen wir dies eine containerübergreifende Transaktion. In einer solchen Transaktion ist es wichtig, dass der speicheroptimierte Teil der Transaktion auf der Transaktionsisolationsstufe namens SNAPSHOT ausgeführt wird.

Um diese Stufe für speicheroptimierte Tabellen in einer containerübergreifenden Transaktion zuverlässig zu erzwingen, ändern Sie Ihre Datenbankeinstellung durch das Ausführen der folgenden T-SQL.

ALTER DATABASE CURRENT
    SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = ON;

3. Erstellen einer optimierten FILEGROUP

Auf Microsoft SQL Server müssen Sie vor der Erstellung einer speicheroptimierten Tabelle zunächst eine FILEGROUP erstellen und für diese die Angabe CONTAINS MEMORY_OPTIMIZED_DATA vornehmen. Die FILEGROUP wird Ihrer Datenbank zugewiesen. Einzelheiten dazu finden Sie unter:

Auf Azure SQL-Datenbank können und brauchen Sie keine solche FILEGROUP erstellen.

Das folgende T-SQL-Beispielskript aktiviert eine Datenbank für In-Memory-OLTP und konfiguriert alle empfohlene Einstellungen. Es funktioniert mit SQL Server und Azure SQL-Datenbank: enable-in-memory-oltp.sql.

Beachten Sie, dass nicht alle Features von SQL Server für Datenbanken mit einer MEMORY_OPTIMIZED_DATA-Dateigruppe unterstützt werden. Weitere Informationen zu den Einschränkungen finden Sie unter Nicht unterstützte SQL Server-Funktionen für In-Memory OLTP.

4. Erstellen einer speicheroptimierten Tabelle

Das entscheidende Transact-SQL-Schlüsselwort ist das MEMORY_OPTIMIZED-Schlüsselwort.

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

Die Transact-SQL-INSERT und SELECT-Anweisungen für eine speicheroptimierte Tabelle sind die gleichen wie für eine normale Tabelle.

ALTER TABLE für speicheroptimierte Tabellen

ALTER TABLE...ADD/DROP können eine Spalte aus einer speicheroptimierten Tabelle oder einem Index hinzufügen oder entfernen.

  • CREATE INDEX und DROP INDEX können nicht für speicheroptimierte Tabellen ausgeführt werden. Verwenden Sie stattdessen ALTER TABLE ... ADD/DROP INDEX.
  • Weitere Informationen finden Sie unter Ändern von speicheroptimierten Tabellen.

Planen Sie Ihre speicheroptimierten Tabellen und Indizes.

5. Erstellen einer nativ kompilierten, gespeicherten Prozedur (native Prozedur)

Das entscheidende Schlüsselwort ist 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;  

Das Schlüsselwort SCHEMABINDING bedeutet, dass die Tabellen in der nativen Prozedur nicht gelöscht werden können, es sei denn, die native Prozedur wird zuvor gelöscht. Weitere Informationen finden Sie unter Erstellen systemintern kompilierter gespeicherter Prozeduren.

Beachten Sie, dass Sie keine nativ kompilierte gespeicherte Prozedur erstellen müssen, um auf eine speicheroptimierte Tabelle zuzugreifen. Sie können auf speicheroptimierte Tabellen auch von herkömmlich gespeicherten Prozeduren und Ad-hoc-Batches verweisen.

6. Ausführen der nativen Prozedur

Füllen Sie die Tabelle mit zwei Zeilen mit Daten auf.

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

Dann folgt ein EXECUTE-Aufruf auf die systemintern kompilierte gespeicherte Prozedur.

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

Hier sehen Sie die tatsächliche PRINT-Ausgabe:

-- 2 = Latest SalesOrderId, for CustomerId = 42  

Anleitung zur Dokumentation und nächste Schritte

Die vorhergehenden, einfachen Beispiele bieten Ihnen eine Grundlage zum Erlernen der erweiterten Funktionen von In-Memory-OLTP. Die folgenden Abschnitte sind eine Anleitung für die speziellen Überlegungen, die Sie möglicherweise kennen sollten, und wo Sie die Details von diesen finden können.

So arbeiten In-Memory-OLTP-Funktionen so viel schneller

In den folgenden Unterabschnitten wird kurz beschrieben, wie die In-Memory-OLTP-Funktionen intern arbeiten, um verbesserte Leistung zu bieten.

So werden speicheroptimierte Tabellen schneller ausgeführt

Dualer Aufbau: Eine speicheroptimierte Tabelle ist dual aufgebaut; eine Darstellung im aktiven Arbeitsspeicher, und die andere auf der Festplatte. Jede Transaktion wird in beiden Versionen der Tabelle committet. Transaktionen arbeiten gegen die Darstellung des viel schnelleren aktiven Arbeitsspeichers. Speicheroptimierte Tabellen profitieren von der höheren Geschwindigkeit des aktiven Arbeitsspeichers im Vergleich zum Datenträger. Darüber hinaus erlaubt die höhere Agilität des aktiven Speichers die Verwendung einer komplexeren, auf Geschwindigkeit optimierten Tabellenstruktur. Zusätzlich ist die erweiterte Struktur seitenlos, wodurch der Mehraufwand sowie der Konflikt von Latches und Spinlocks vermieden werden.

Keine Sperren: Die speicheroptimierte Tabelle basiert auf einem optimistischen Ansatz für die konkurrierenden Ziele der Datenintegrität gegenüber Parallelität und hohem Durchsatz. Während der Transaktion platziert die Tabelle keine Sperren auf keiner Version der aktualisierten Zeilen von Daten. Diese kann im Konflikte erheblich in einigen Systemen mit hohem Volumen reduzieren.

Zeilenversionen: Anstelle von Sperren fügt die speicheroptimierte Tabelle eine neue Version einer aktualisierten Zeile in die Tabelle selbst ein, nicht in „tempdb“. Die ursprüngliche Zeile wird beibehalten, nachdem für die Transaktion ein Commit ausgeführt wurde. Während der Transaktion können andere Prozesse die ursprüngliche Version der Zeile lesen.

  • Wenn mehrere Versionen einer Zeile für eine datenträgerbasierte Tabelle erstellt werden, werden Zeilenversionen vorübergehend in „tempdb“ gespeichert.

Weniger Protokollierung: Die Versionen der Zeilen vor und nach der Aktualisierung werden in der speicheroptimierten Tabelle gespeichert. Das Zeilenpaar stellt einen Großteil der Informationen bereit, die normalerweise in die Protokolldatei geschrieben werden. Dadurch kann das System weniger Informationen in das Protokoll schreiben und auch nicht so häufig. Die Transaktionsintegrität wird nichtsdestotrotz sichergestellt.

So werden native Prozeduren schneller ausgeführt

Konvertieren einer regulär interpretierten, gespeicherten Prozedur in eine nativ kompilierte gespeicherte Prozedur reduziert erheblich die Anzahl der Anweisungen, die während der Laufzeit ausgeführt wird.

Vor- und Nachteile von In-Memory-Funktionen

Wie es in der Informatik üblich ist, sind die durch In-Memory-Funktionen bereitgestellte Leistungsgewinne ein Kompromiss. Die bessere Funktionen bringen Vorteile mit sich, die bedeutender als die zusätzlichen Kosten für die Funktion sind. Umfassende Hinweise zu den Vor- und Nachteilen finden Sie unter:

Im Rest dieses Abschnitts werden einige der wichtigsten Aspekte hinsichtlich Planung und Vor- und Nachteilen aufgelistet.

Vor- und Nachteile von speicheroptimierten Tabellen

Schätzen Sie den Arbeitsspeicher: Sie müssen die Menge des aktiven Arbeitsspeichers schätzen, den Ihre speicheroptimierte Tabelle verbrauchen wird. Ihr Computersystem muss über ausreichend Kapazität zum Hosten einer speicheroptimierten Tabelle verfügen. Einzelheiten dazu finden Sie unter:

Partitionieren Sie Ihre große Tabelle: Eine Möglichkeit, den Bedarf an großer Menge aktiven Arbeitsspeichers zu decken, ist das Partitionieren Ihrer große Tabelle in Teile im Arbeitsspeicher, die heiße Datenzeilen enthalten, verglichen mit kalte, alte Datenzeilen, die auf der Festplatte gespeichert werden (z.B. Aufträge, die vollständig ausgeliefert und abgeschlossen wurden). Diese Partitionierung ist ein manueller Prozess von Entwurf und Implementierung. Thema

Vor-und Nachteile von nativen Prozeduren

  • Eine nativ kompilierte gespeicherte Prozedur kann nicht auf datenträgerbasierte Tabellen zugreifen. Eine native Prozedur kann nur auf speicheroptimierte Tabellen zugreifen.
  • Wenn eine native Prozedur zum ersten Mal ausgeführt wird, nachdem der Server oder die Datenbank zuletzt wieder online geschaltet wurde, muss die native Prozedur einmalig neu kompiliert werden. Dies führt zu einer Verzögerung, bevor die native Prozedur mit der Ausführung beginnt.

Zusätzliche Überlegungen zu speicheroptimierten Tabellen

Indizes für speicheroptimierten Tabellen unterscheiden sich in einigen Punkten von Indizes in Tabellen auf herkömmlichen Datenträgern. Hashindizes sind nur für speicheroptimierte Tabellen verfügbar.

Sie müssen planen, um sicherzustellen, dass genügend aktiver Speicher für Ihre geplante speicheroptimierte Tabelle und ihre Indizes vorhanden sein wird. Thema

Eine speicheroptimierte Tabelle kann mit DURABILITY = SCHEMA_ONLY deklariert werden:

  • Diese Syntax weist das System an, alle Daten aus der speicheroptimierten Tabelle zu verwerfen, wenn die Datenbank offline geschaltet wird. Nur die Tabellendefinition wird beibehalten.
  • Wenn die Datenbank wieder online geschaltet wird, wird die speicheroptimierte Tabelle ohne Daten zurück in den aktiven Arbeitsspeicher geladen.
  • SCHEMA_ONLY-Tabellen können eine übergeordnete Alternative zu #temporären Tabellen in tempdb darstellen, wenn tausende Zeilen involviert sind.

Tabellenvariablen können auch als speicheroptimiert deklariert werden. Thema

Zusätzliche Überlegungen zu nativ kompilierten Modulen

Die Typen von nativ kompilierten Modulen, die über Transact-SQL verfügbar sind, sind:

Eine nativ kompilierte benutzerdefinierte Funktion (UDF) wird schneller ausgeführt als eine interpretierte UDF. Hier sind einige Punkte, die bei UDFs zu beachten sind:

  • Wenn T-SQL-SELECT eine UDF verwendet, wird die UDF immer einmal pro zurückgegebener Zeile aufgerufen.
    • UDFs werden nie Inline ausgeführt, und stattdessen immer aufgerufen.
    • Die Ersparnis ist durch das Kompilieren ist weniger ausschlaggebend als der für alle UDFs inhärente Aufwand für wiederholte Aufrufe.
    • Dennoch ist der Mehraufwand für UDF-Aufrufe im Praktischen oft akzeptabel.

Testdaten und Erläuterung zur Leistung von nativen UDFs finden Sie unter:

Dokumentationshandbuch für speicheroptimierte Tabellen

Weitere Informationen finden Sie in diesen Artikeln, in denen spezielle Überlegungen zu speicheroptimierten Tabellen erläutert werden:

Dokumentationshandbuch für native Prozeduren

Im folgenden Artikel und dessen untergeordneten Artikel im Inhaltsverzeichnis sind die Details zu nativ kompilierten gespeicherten Prozeduren aufgeführt.

Hier finden Sie Artikel, die Code zum Veranschaulichen der Leistungsverbesserungen bieten, die Sie mit In-Memory-OLTP erreichen können.