SQL Server unterstützt partitionierte Tabellen und Indizes. Wenn eine partitionierte Tabelle oder ein partitionierter Index partitioniert wird, werden ihre Daten in Einheiten unterteilt, die über mehr als eine Dateigruppe verteilt werden können.
Um eine partitionierte Tabelle in SQL Server zu erstellen, müssen Sie daher zuerst die Dateigruppe(n) erstellen, die jede Partition enthalten. Außerdem müssen Sie eine Partitionsfunktion und ein Partitionsschema erstellen.
Das geht also so:
- Dateigruppe(n) erstellen
- Erstellen Sie eine Partitionsfunktion
- Erstellen Sie ein Partitionsschema
- Erstellen Sie die partitionierte Tabelle
Nachfolgend finden Sie ein Beispiel für die Verwendung dieser Schritte zum Erstellen einer Tabelle mit vier Partitionen.
Dateigruppen erstellen
Zuerst fügen wir der Datenbank vier Dateigruppen mit dem Namen Test hinzu , und geben Sie dann die physische Datei für jede dieser Dateigruppen an.
ALTER DATABASE Test
ADD FILEGROUP MoviesFg1;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg2;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg3;
GO
ALTER DATABASE Test
ADD FILEGROUP MoviesFg4;
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg1dat,
FILENAME = '/var/opt/mssql/data/MoviesFg1dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg1;
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg2dat,
FILENAME = '/var/opt/mssql/data/MoviesFg2dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg2;
GO
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg3dat,
FILENAME = '/var/opt/mssql/data/MoviesFg3dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg3;
GO
ALTER DATABASE Test
ADD FILE
(
NAME = MoviesFg4dat,
FILENAME = '/var/opt/mssql/data/MoviesFg4dat.ndf',
SIZE = 5MB,
MAXSIZE = 100MB,
FILEGROWTH = 5MB
)
TO FILEGROUP MoviesFg4;
GO
Sie müssen diesen Code je nach Ihren Anforderungen ändern. Sie müssen auch die Dateipfade an Ihre Umgebung anpassen. Unter Windows sieht Ihr Pfad beispielsweise eher wie D:\mssql\data\MoviesFg4dat.ndf
aus .
Wenn Sie weitere Partitionen benötigen, fügen Sie hier weitere Dateigruppen hinzu. Wenn Sie hingegen weniger Partitionen benötigen, geben Sie hier weniger Dateigruppen an.
Erstellen Sie eine Partitionsfunktion
Als nächstes erstellen wir eine Partitionsfunktion namens MoviesPartitionFunction das wird die Tabelle in vier Partitionen partitionieren.
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO
Der int part gibt den Datentyp der für die Partitionierung verwendeten Spalte an.
Alle Datentypen außer Text sind für die Verwendung als Partitionierungsspalten gültig , ntext , Bild , xml , Zeitstempel , varchar(max) , nvarchar(max) , varbinary(max) , Alias-Datentypen oder benutzerdefinierte CLR-Datentypen.
Hier verwende ich drei Grenzwerte (1, 100
, und 1000
), um vier Partitionen anzugeben. Diese Grenzwerte müssen entweder mit dem in Klammern nach dem Namen der Partitionsfunktion angegebenen Datentyp übereinstimmen oder implizit in diesen konvertierbar sein.
Angesichts dieser Grenzwerte und der Tatsache, dass ich einen RANGE LEFT
angegeben habe Partition enthalten die vier Partitionen die in der folgenden Tabelle angegebenen Werte.
Partition | Werte |
---|---|
1 | <= 1 |
2 | > 1 UND <= 100 |
3 | > 100 UND <=1000 |
4 | > 1000 |
Wenn ich einen RANGE RIGHT
angegeben hätte Partition, wäre die Aufschlüsselung etwas anders, wie in der folgenden Tabelle dargestellt.
Partition | Werte |
---|---|
1 | < 1 |
2 | >= 1 UND < 100 |
3 | >= 100 UND < 1000 |
4 | >= 1000 |
Dasselbe Konzept gilt, wenn die Partitionierungsspalte andere Datentypen verwendet, z. B. Datums-/Uhrzeitwerte.
Erstellen Sie ein Partitionsschema
Als nächstes müssen wir ein Partitionsschema erstellen.
Ein Partitionsschema ordnet die Partitionen einer partitionierten Tabelle oder eines partitionierten Index den neuen Dateigruppen zu.
In unserem Fall sieht der Code so aus:
CREATE PARTITION SCHEME MoviesPartitionScheme
AS PARTITION MoviesPartitionFunction
TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);
GO
Beachten Sie, dass wir auf die Partitionsfunktion verweisen, die wir im vorherigen Schritt erstellt haben. Wir verweisen auch auf die Dateigruppen, die wir im ersten Schritt erstellt haben.
Erstellen Sie die partitionierte Tabelle
Schließlich können wir die partitionierte Tabelle erstellen.
CREATE TABLE Movies (
MovieId int IDENTITY PRIMARY KEY,
MovieName varchar(60)
)
ON MoviesPartitionScheme (MovieId);
GO
Der einzige Unterschied zwischen diesem und dem Erstellen einer unpartitionierten Tabelle besteht darin, dass wir beim Erstellen einer partitionierten Tabelle den ON
verwenden -Argument, um ein zu verwendendes Partitionsschema anzugeben. In unserem Fall geben wir das Partitionsschema an, das wir im vorherigen Schritt erstellt haben, und geben die MovieId an Spalte als Partitionierungsspalte.
Sie werden feststellen, dass die MovieId Spalte hat den Datentyp int , was den Grenzwerten entspricht, die wir beim Erstellen der Partitionsfunktion angegeben haben.
Beachten Sie, dass, wenn Sie eine berechnete Spalte in einer Partitionsfunktion verwenden, diese ausdrücklich als PERSISTED
gekennzeichnet werden muss .
Prüfen Sie die Partitionsfunktion
Sie können die sys.partition_functions
verwenden view, um alle Partitionsfunktionen zurückzugeben.
SELECT * FROM sys.partition_functions;
Ergebnis (bei vertikaler Ausgabe):
Prüfen Sie das Partitionsschema
Sie können sys.partition_schemes
verwenden um das Partitionsschema zu überprüfen.
SELECT * FROM sys.partition_schemes;
Ergebnis (bei vertikaler Ausgabe):
Alternativ können Sie die folgende Abfrage verwenden, um andere Details wie Schema, Tabelle, Index usw. zurückzugeben.
SELECT
object_schema_name(i.object_id) AS [Schema],
object_name(i.object_id) AS [Object],
i.name AS [Index],
s.name AS [Partition Scheme]
FROM sys.indexes i
INNER JOIN sys.partition_schemes s ON i.data_space_id = s.data_space_id;
Ergebnis (bei vertikaler Ausgabe):
Schema | dboObject | FilmeIndex | PK__Movies__4BD2941A0ED85ACAPartitionsschema | MoviesPartitionScheme
Prüfen Sie die partitionierte Tabelle
Sie können sys.dm_db_partition_stats
ausführen view, um Seiten- und Zeilenanzahlinformationen für jede Partition in der aktuellen Datenbank zurückzugeben.
Aber wenn Sie das ausführen, bevor Sie irgendwelche Daten in die Tabelle einfügen, werden die meisten Statistiken Null sein.
Also werde ich zuerst Daten einfügen.
INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;
Ergebnis:
(4079 Zeilen betroffen)
Wir können sehen, dass 4.079 Zeilen eingefügt wurden.
Lassen Sie uns nun die sys.dm_db_partition_stats
abfragen ansehen.
SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Ergebnis:
+--------------+------------+------------ +--------------------+---------------------+- ---------------------+------------------------ ------+---------------+-------------- --------+-------------------------------+-------- -----------------------+-------------------+- ----------------------+-------------+| partition_id | Objekt-ID | index_id | Partitionsnummer | in_row_data_page_count | in_row_used_page_count | in_row_reserved_page_count | lob_used_page_count | lob_reserved_page_count | row_overflow_used_page_count | row_overflow_reserved_page_count | used_page_count | reservierte_seitenzahl | Zeilenanzahl ||------+------------+------------+ --------------------+-------------------------+-- ------------------------+-------------------- -----+-----------------------+-------------------- ------+--------------------------------+--------- ----------------------------+-------------------+-- ---------------------+-------------|| 72057594048413696 | 2030630277 | 1 | 1 | 1 | 2 | 9 | 0 | 0 | 0 | 0 | 2 | 9 | 1 || 72057594048479232 | 2030630277 | 1 | 2 | 1 | 2 | 9 | 0 | 0 | 0 | 0 | 2 | 9 | 99 || 72057594048544768 | 2030630277 | 1 | 3 | 3 | 5 | 25 | 0 | 0 | 0 | 0 | 5 | 25 | 900 || 72057594048610304 | 2030630277 | 1 | 4 | 10 | 12 | 33 | 0 | 0 | 0 | 0 | 12 | 33 | 3079 |+--------------+------------+------------+ --------------------+-------------------------+-- ------------------------+-------------------- -----+-----------------------+-------------------- ------+--------------------------------+--------- ----------------------------+-------------------+-- ---------------------+-------------+
Diese Ansicht gibt viele Spalten zurück, also grenzen wir die Spalten auf ein paar ein.
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Ergebnis:
+--------------------+---------------------+| Partitionsnummer | Zeilenanzahl ||--------------------+---------------------|| 1 | 1 || 2 | 99 || 3 | 900 || 4 | 3079 |+--------------------+---------------------+
Wir können sehen, wie die Zeilen über die Partitionen verteilt sind. Sie werden genau so zugewiesen, wie wir es in der Partitionsfunktion angegeben haben. Die Zeilen umfassen insgesamt 4.079, genau so viele Zeilen haben wir eingefügt.
Es ist jedoch erwähnenswert, dass die Microsoft-Dokumentation tatsächlich besagt, dass diese Spalte nur ein ungefährer Wert ist Anzahl der Zeilen in jeder Partition.
Best Practice
Microsoft empfiehlt, immer leere Partitionen an beiden Enden des Partitionsbereichs beizubehalten.
Dies ist für den Fall, dass Sie die Partitionen in Zukunft entweder aufteilen oder zusammenführen müssen.
Der Grund für diese Empfehlung besteht darin, sicherzustellen, dass die Partitionsteilung und die Partitionszusammenführung keine unerwarteten Datenverschiebungen nach sich ziehen.
Angesichts der Daten in meinem Beispiel könnte ich daher die Partitionsfunktion so ändern, dass sie etwa so aussieht:
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO
Oder wenn ich mit mehr als 10.000 Zeilen rechne, könnte ich eine größere Zahl verwenden (oder mehr Partitionen erstellen).
Wenn ich alle Schritte erneut erstellen würde, um meine partitionierte Tabelle zu erstellen, würden meine Partitionsstatistiken wie folgt aussehen:
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Ergebnis:
+--------------------+---------------------+| Partitionsnummer | Zeilenanzahl ||--------------------+---------------------|| 1 | 0 || 2 | 100 || 3 | 3979 || 4 | 0 |+--------------------+-------------+
Jetzt sind meine Daten in den mittleren zwei Partitionen konzentriert und die Partitionen an beiden Enden sind leer.