Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:SQL Server
Azure SQL-Datenbank
Azure SQL Managed Instance
In-Memory OLTP unterstützt ein Anwendungsentwurfsmuster, das die Leistung für aktuelle Daten priorisiert. Dieses Muster gilt, wenn aktuelle Daten wesentlich häufiger gelesen oder aktualisiert werden als ältere Daten. Die aktuellen Daten werden als aktiv oder heiß betrachtet, und die älteren Daten sind kalt.
Der Hauptgedanke besteht darin, heiße Daten in einer speicheroptimierten Tabelle zu speichern. Auf wöchentlicher oder monatlicher Basis werden ältere Daten, die kalt werden, in eine partitionierte Tabelle verschoben. In der partitionierten Tabelle werden die Daten auf einem Datenträger oder auf einer anderen Festplatte und nicht im Arbeitsspeicher gespeichert.
In der Regel verwendet dieser Entwurf einen Datetime2-Schlüssel , um den Verschiebungsprozess zu ermöglichen, um zwischen heißen und kalten Daten effizient zu unterscheiden.
Erweiterte Partitionierung
Der Entwurf soll eine partitionierte Tabelle mit einer speicheroptimierten Partition imitieren. Damit dieser Entwurf funktioniert, stellen Sie sicher, dass die Tabellen ein gemeinsames Schema verwenden. Das Codebeispiel weiter unten in diesem Artikel veranschaulicht dieses Verfahren.
Neue Daten werden immer als heiß betrachtet. Heiße Daten werden in die speicheroptimierte Tabelle eingefügt und aktualisiert. Kalte Daten werden in der herkömmlichen partitionierten Tabelle beibehalten. Eine gespeicherte Prozedur fügt in regelmäßigen Abständen eine neue Partition hinzu. Die Partition enthält die neuesten Kaltdaten, die aus der speicheroptimierten Tabelle verschoben wurden.
Wenn für einen Vorgang nur heiße Daten benötigt werden, können nativ kompilierte gespeicherte Prozeduren für den Zugriff auf die Daten verwendet werden. Vorgänge, bei denen auf heiße oder kalte Daten zugegriffen wird, müssen interpretiertes Transact-SQL verwenden, um die speicheroptimierte Tabelle mit der partitionierten Tabelle zu verknüpfen.
Hinzufügen einer Partition
Daten, die kürzlich kalt wurden, müssen in die partitionierte Tabelle verschoben werden. Die Schritte für diesen regelmäßigen Partitionsaustausch lauten wie folgt:
Legen Sie für die Daten in der speicheroptimierten Tabelle den datetime-Wert fest, der die Grenze bzw. den Umstellungszeitpunkt für die heißen bzw. neuen kalten Daten darstellt.
Fügen Sie die neuen, kalten Daten aus der In-Memory-OLTP-Tabelle in eine
cold_staging-Tabelle ein.Löschen Sie diese kalten Daten aus der speicheroptimierten Tabelle.
Verschieben Sie die
cold_stagingTabelle in eine Partition.Fügen Sie die Partition hinzu.
Wartungsfenster
Einer der vorangegangenen Schritte besteht darin, die neuen kalten Daten aus der speicheroptimierten Tabelle zu löschen. Es gibt ein Zeitintervall zwischen diesem Löschvorgang und dem letzten Schritt, der die neue Partition hinzufügt. In diesem Intervall schlägt jede Anwendung, die versucht, die neu kalten Daten zu lesen, fehl.
Ein Beispiel dazu finden Sie unter Partitionierung auf Anwendungsebene.
Codebeispiel
Das folgende Transact-SQL-Beispiel wird nur für die vereinfachte Darstellung in mehreren kleineren Codeblöcken angezeigt. Für Ihre Tests könnten Sie alle an einen großen Codeblock anfügen.
Insgesamt zeigt das T-SQL-Beispiel, wie eine speicheroptimierte Tabelle mit einer partitionierten, datenträgerbasierten Tabelle verwendet wird.
In den ersten Phasen des T-SQL-Beispiels werden zunächst die Datenbank und anschließend Objekte wie Tabellen in der Datenbank erstellt. In den weiteren Phasen wird gezeigt, wie Daten aus einer speicheroptimierten Tabelle in eine partitionierte Tabelle verschoben werden.
Erstellen einer Datenbank
In diesem Abschnitt des T-SQL-Beispiels wird eine Testdatenbank erstellt. Die Datenbank ist so konfiguriert, dass sowohl speicheroptimierte Tabellen als auch partitionierte Tabellen unterstützt werden.
CREATE DATABASE PartitionSample;
GO
-- Add a FileGroup, enabled for In-Memory OLTP.
-- Change file path as needed.
ALTER DATABASE PartitionSample
ADD FILEGROUP PartitionSample_mod
CONTAINS MEMORY_OPTIMIZED_DATA;
ALTER DATABASE PartitionSample
ADD FILE (
NAME = 'PartitionSample_mod',
FILENAME = 'C:\data\PartitionSample_mod')
TO FILEGROUP PartitionSample_mod;
GO
Erstellen einer speicheroptimierten Tabelle für heiße Daten
In diesem Abschnitt wird die speicheroptimierte Tabelle erstellt, in der die neuesten Daten enthalten sind. Bei diesen Daten handelt es sich noch immer größtenteils um heiße Daten.
USE PartitionSample;
GO
-- Create a memory-optimized table for the HOT Sales Order data.
-- Notice the index that uses DATETIME2.
CREATE TABLE dbo.SalesOrders_hot
(
so_id INT IDENTITY PRIMARY KEY NONCLUSTERED,
cust_id INT NOT NULL,
so_date DATETIME2 NOT NULL INDEX ix_date NONCLUSTERED,
so_total MONEY NOT NULL,
INDEX ix_date_total NONCLUSTERED (so_date DESC, so_total DESC)
)
WITH (MEMORY_OPTIMIZED = ON);
GO
Erstellen einer partitionierten Tabelle für kalte Daten
In diesem Abschnitt wird die partitionierte Tabelle erstellt, in der die kalten Daten enthalten sind.
-- Create a partition and table for the COLD Sales Order data.
-- Notice the index that uses DATETIME2.
CREATE PARTITION FUNCTION [ByDatePF](DATETIME2)
AS RANGE RIGHT
FOR VALUES ();
GO
CREATE PARTITION SCHEME [ByDateRange]
AS PARTITION [ByDatePF]
ALL TO ([PRIMARY]);
GO
CREATE TABLE dbo.SalesOrders_cold
(
so_id INT NOT NULL,
cust_id INT NOT NULL,
so_date DATETIME2 NOT NULL,
so_total MONEY NOT NULL,
CONSTRAINT PK_SalesOrders_cold PRIMARY KEY (so_id, so_date),
INDEX ix_date_total NONCLUSTERED (so_date DESC, so_total DESC)
) ON [ByDateRange](so_date);
GO
Erstellen einer Tabelle zum Speichern kalter Daten während der Verschiebung
In diesem Abschnitt wird die cold_staging Tabelle erstellt. Es wird auch eine Ansicht erstellt, in der die aktiven und kalten Daten aus den beiden Tabellen zusammengeführt werden.
-- A table used to briefly stage the newly cold data, during moves to a partition.
CREATE TABLE dbo.SalesOrders_cold_staging
(
so_id INT NOT NULL,
cust_id INT NOT NULL,
so_date DATETIME2 NOT NULL,
so_total MONEY NOT NULL,
CONSTRAINT PK_SalesOrders_cold_staging PRIMARY KEY (so_id, so_date),
CONSTRAINT CHK_SalesOrders_cold_staging CHECK (so_date >= '1900-01-01'),
INDEX ix_date_total NONCLUSTERED (so_date DESC, so_total DESC)
);
GO
-- A view, for retrieving the aggregation of hot plus cold data.
CREATE VIEW dbo.SalesOrders AS
SELECT so_id,
cust_id,
so_date,
so_total,
1 AS 'is_hot'
FROM dbo.SalesOrders_hot
UNION ALL
SELECT so_id,
cust_id,
so_date,
so_total,
0 AS 'is_cold'
FROM dbo.SalesOrders_cold;
GO
Erstellen der gespeicherten Prozedur
In diesem Abschnitt wird die gespeicherte Prozedur erstellt, die Sie regelmäßig ausführen. Die Prozedur verschiebt neue kalte Daten aus der speicheroptimierten Tabelle in die partitionierte Tabelle.
Note
Wenn Sie diese Prozedur schnell hintereinander aufrufen, SYSDATETIME() wird möglicherweise derselbe Datetime2-Wert für aufeinander folgende Aufrufe zurückgegeben. In diesem Fall ALTER PARTITION FUNCTION ... SPLIT RANGE tritt ein Fehler mit Fehler 7721 auf, da der Grenzwert bereits in der Partitionsfunktion vorhanden ist. Rufen Sie die Prozedur in Abständen auf, sodass der @splitdate-Wert bei jedem Aufruf eindeutig ist.
-- A stored procedure to move all newly cold sales orders data
-- to its staging location.
CREATE PROCEDURE dbo.usp_SalesOrdersOffloadToCold
@splitdate DATETIME2
AS
BEGIN
BEGIN TRANSACTION;
-- Insert the cold data as a temporary heap.
INSERT INTO dbo.SalesOrders_cold_staging WITH (TABLOCKX)
SELECT so_id,
cust_id,
so_date,
so_total
FROM dbo.SalesOrders_hot WITH (SERIALIZABLE)
WHERE so_date < @splitdate;
-- Delete the moved data from the hot table.
DELETE dbo.SalesOrders_hot WITH (SERIALIZABLE)
WHERE so_date < @splitdate;
-- Update the partition function, and switch in the new partition.
ALTER PARTITION SCHEME [ByDateRange] NEXT USED [PRIMARY];
DECLARE @p AS INT = (SELECT MAX(partition_number)
FROM sys.partitions
WHERE object_id = OBJECT_ID('dbo.SalesOrders_cold'));
EXECUTE sp_executesql N'ALTER TABLE dbo.SalesOrders_cold_staging
SWITCH TO dbo.SalesOrders_cold partition @i', N'@i int', @i = @p;
ALTER PARTITION FUNCTION [ByDatePF]()
SPLIT RANGE (@splitdate);
-- Modify a constraint on the cold_staging table, to align with new partition.
ALTER TABLE dbo.SalesOrders_cold_staging
DROP CONSTRAINT CHK_SalesOrders_cold_staging;
DECLARE @s AS NVARCHAR (100) = CONVERT (NVARCHAR (100), @splitdate, 121);
DECLARE @sql AS NVARCHAR (1000) = N'ALTER TABLE dbo.SalesOrders_cold_staging
ADD CONSTRAINT CHK_SalesOrders_cold_staging CHECK (so_date >= ''' + @s + ''')';
PRINT @sql;
EXECUTE sp_executesql @sql;
COMMIT TRANSACTION;
END
GO
Vorbereiten von Beispieldaten und Veranschaulichung der gespeicherten Prozedur
In diesem Abschnitt werden Beispieldaten generiert und eingefügt. Anschließend wird die gespeicherte Prozedur zur Veranschaulichung ausgeführt.
-- Insert sample values into the hot table.
INSERT INTO dbo.SalesOrders_hot
VALUES (1, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot
VALUES (1, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot
VALUES (1, SYSDATETIME(), 1);
GO
-- Verify that the hot data is in the table, by selecting from the view.
SELECT *
FROM dbo.SalesOrders;
GO
-- Treat all data in the hot table as cold data:
-- Run the stored procedure, to move (offload) all sales orders to date to cold storage.
DECLARE @t AS DATETIME2 = SYSDATETIME();
EXECUTE dbo.usp_SalesOrdersOffloadToCold @t;
-- Again, read hot plus cold data from the view.
SELECT *
FROM dbo.SalesOrders;
GO
-- Retrieve the name of every partition.
SELECT OBJECT_NAME(object_id),
*
FROM sys.dm_db_partition_stats AS ps
WHERE object_id = OBJECT_ID('dbo.SalesOrders_cold');
-- Insert more data into the hot table.
INSERT INTO dbo.SalesOrders_hot
VALUES (2, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot
VALUES (2, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot
VALUES (2, SYSDATETIME(), 1);
GO
-- Read hot plus cold data from the view.
SELECT *
FROM dbo.SalesOrders;
GO
-- Again, run the stored procedure, to move all sales orders to date to cold storage.
DECLARE @t AS DATETIME2 = SYSDATETIME();
EXECUTE dbo.usp_SalesOrdersOffloadToCold @t;
-- Read hot plus cold data from the view.
SELECT *
FROM dbo.SalesOrders;
GO
-- Again, retrieve the name of every partition.
-- The stored procedure can modify the partitions.
SELECT OBJECT_NAME(object_id),
partition_number,
row_count
FROM sys.dm_db_partition_stats AS ps
WHERE object_id = OBJECT_ID('dbo.SalesOrders_cold')
AND index_id = 1;
Löschen aller für die Veranschaulichung verwendeten Objekte
Denken Sie daran, die für die Veranschaulichung verwendete Testdatenbank vom Testsystem zu entfernen.
USE master;
GO
DROP DATABASE PartitionSample;
GO