SQL Server ondersteunt gepartitioneerde tabellen en indexen. Wanneer een gepartitioneerde tabel of index is gepartitioneerd, worden de gegevens opgedeeld in eenheden die over meer dan één bestandsgroep kunnen worden verspreid.
Om een gepartitioneerde tabel in SQL Server te maken, moet u daarom eerst de bestandsgroep(en) maken die elke partitie bevatten. U moet ook een partitiefunctie en een partitieschema maken.
Dus het gaat als volgt:
- Bestandsgroep(en) maken
- Maak een partitiefunctie
- Maak een partitieschema
- Maak de gepartitioneerde tabel
Hieronder ziet u een voorbeeld van het gebruik van deze stappen om een tabel met vier partities te maken.
Bestandsgroepen maken
Eerst voegen we vier bestandsgroepen toe aan de database genaamd Test en specificeer vervolgens het fysieke bestand voor elk van die bestandsgroepen.
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
U moet deze code wijzigen, afhankelijk van uw vereisten. U moet ook de bestandspaden aanpassen aan uw omgeving. Als u bijvoorbeeld Windows gebruikt, kan uw pad er meer uitzien als D:\mssql\data\MoviesFg4dat.ndf
.
Als je meer partities nodig hebt, voeg dan hier meer bestandsgroepen toe. Omgekeerd, als je minder partities nodig hebt, specificeer dan hier minder bestandsgroepen.
Een partitiefunctie maken
Vervolgens maken we een partitiefunctie genaamd MoviesPartitionFunction dat zal de tafel in vier partities verdelen.
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO
De int part specificeert het datatype van de kolom die wordt gebruikt voor partitionering.
Alle datatypes zijn geldig voor gebruik als partitioneringskolommen, behalve tekst , ntekst , afbeelding , xml , tijdstempel , varchar(max) , nvarchar(max) , varbinary(max) , aliasgegevenstypen of door de gebruiker gedefinieerde CLR-gegevenstypen.
Hier gebruik ik drie grenswaarden (1, 100
, en 1000
) om vier partities op te geven. Deze grenswaarden moeten overeenkomen met of impliciet converteerbaar zijn naar het gegevenstype dat tussen haakjes achter de naam van de partitiefunctie staat aangegeven.
Gezien deze grenswaarden en het feit dat ik een RANGE LEFT
. heb opgegeven partitie, zullen de vier partities waarden bevatten zoals gespecificeerd in de volgende tabel.
Partitie | Waarden |
---|---|
1 | <= 1 |
2 | > 1 EN <= 100 |
3 | > 100 EN <=1000 |
4 | > 1000 |
Als ik een RANGE RIGHT
. had opgegeven partitie, zou de verdeling iets anders zijn, zoals uiteengezet in de volgende tabel.
Partitie | Waarden |
---|---|
1 | < 1 |
2 | >= 1 AND < 100 |
3 | >= 100 AND < 1000 |
4 | >= 1000 |
Hetzelfde concept is van toepassing als de partitiekolom andere gegevenstypen gebruikt, zoals datum/tijd-waarden.
Een partitieschema maken
Vervolgens moeten we een partitieschema maken.
Een partitieschema wijst de partities van een gepartitioneerde tabel of index toe aan de nieuwe bestandsgroepen.
In ons geval ziet de code er als volgt uit:
CREATE PARTITION SCHEME MoviesPartitionScheme
AS PARTITION MoviesPartitionFunction
TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);
GO
Merk op dat we verwijzen naar de partitiefunctie die we in de vorige stap hebben gemaakt. We verwijzen ook naar de bestandsgroepen die we in de eerste stap hebben gemaakt.
Maak de gepartitioneerde tabel
Eindelijk kunnen we de gepartitioneerde tabel maken.
CREATE TABLE Movies (
MovieId int IDENTITY PRIMARY KEY,
MovieName varchar(60)
)
ON MoviesPartitionScheme (MovieId);
GO
Het enige verschil tussen dit en het maken van een niet-gepartitioneerde tabel is dat we bij het maken van een gepartitioneerde tabel de ON
gebruiken argument om een te gebruiken partitieschema op te geven. In ons geval specificeren we het partitieschema dat we in de vorige stap hebben gemaakt en specificeren we de MovieId kolom als de scheidingskolom.
U zult merken dat de MovieId kolom heeft het gegevenstype int , die overeenkomt met de grenswaarden die we hebben opgegeven bij het maken van de partitiefunctie.
Merk op dat als u een berekende kolom in een partitiefunctie gebruikt, deze expliciet moet worden gemarkeerd als PERSISTED
.
Controleer de partitiefunctie
U kunt de sys.partition_functions
. gebruiken weergave om alle partitiefuncties terug te geven.
SELECT * FROM sys.partition_functions;
Resultaat (met verticale uitvoer):
Controleer het partitieschema
U kunt sys.partition_schemes
. gebruiken om het partitieschema te controleren.
SELECT * FROM sys.partition_schemes;
Resultaat (met verticale uitvoer):
U kunt ook de volgende query gebruiken om andere details terug te geven, zoals het schema, de tabel, de index, enz.
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;
Resultaat (met verticale uitvoer):
Schema | dboObject | FilmsIndex | PK__Movies__4BD2941A0ED85ACApartitieschema | MoviesPartitionScheme
Controleer de gepartitioneerde tabel
U kunt de sys.dm_db_partition_stats
. uitvoeren weergave om pagina- en rij-tellingsinformatie terug te geven voor elke partitie in de huidige database.
Maar als u dat uitvoert voordat u gegevens in de tabel invoert, zullen de meeste statistieken nul zijn.
Dus ik ga eerst gegevens invoegen.
INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;
Resultaat:
(4079 rijen beïnvloed)
We kunnen zien dat er 4.079 rijen zijn ingevoegd.
Laten we nu een query uitvoeren op de sys.dm_db_partition_stats
bekijken.
SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultaat:
+-------------------+-------------+------------ +--------------------+--------------------------+- -------------------------+------------------------ ------+-----------------------+------------------- --------+--------------------------------+-------- ----------------------------+-------------------+- ----------------------+-------------+| partitie_id | object_id | index_id | partitienummer | 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 | gereserveerde_pagina_telling | rij_telling ||-------------------+-------------+------------+ --------------------+--------------------------+-- ------------------------+------------------------- -----+-----------------------+-------------------- -------+--------------------------------+--------- ---------------------------+-------------------+-- ---------------------+-------------|| 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 |+-------------------+-------------+------------+ --------------------+--------------------------+-- ------------------------+------------------------- -----+-----------------------+-------------------- -------+--------------------------------+--------- ---------------------------+-------------------+-- ---------------------+-------------+
Deze weergave levert veel kolommen op, dus laten we de kolommen beperken tot slechts een paar.
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultaat:
+--------------------+-------------+| partitienummer | rij_telling ||--------------------+-------------|| 1 | 1 || 2 | 99 || 3 | 900 || 4 | 3079 |+--------------------+-------------+
We kunnen zien hoe de rijen over de partities zijn verdeeld. Ze zijn precies toegewezen zoals we hebben gespecificeerd in de partitiefunctie. Het totaal aantal rijen is 4.079, wat precies is hoeveel rijen we hebben ingevoegd.
Het is echter vermeldenswaard dat in de Microsoft-documentatie feitelijk staat dat deze kolom slechts een schatting is telling van de rijen in elke partitie.
Beste werkwijze
Microsoft raadt aan dat we altijd lege partities aan beide uiteinden van het partitiebereik houden.
Dit is voor het geval u de partities in de toekomst moet splitsen of samenvoegen.
De reden voor deze aanbeveling is om te garanderen dat het splitsen van partities en het samenvoegen van partities geen onverwachte gegevensverplaatsing veroorzaken.
Daarom zou ik, gezien de gegevens in mijn voorbeeld, de partitiefunctie kunnen wijzigen om er ongeveer zo uit te zien:
CREATE PARTITION FUNCTION MoviesPartitionFunction (int)
AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO
Of als ik meer dan 10.000 rijen verwacht, kan ik een groter aantal gebruiken (of meer partities maken).
Als ik alle stappen opnieuw zou maken om mijn gepartitioneerde tabel te maken, zouden mijn partitiestatistieken er als volgt uitzien:
SELECT
partition_number,
row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');
Resultaat:
+--------------------+-------------+| partitienummer | rij_telling ||--------------------+-------------|| 1 | 0 || 2 | 100 || 3 | 3979 || 4 | 0 |+--------------------+-------------+
Nu zijn mijn gegevens geconcentreerd in de middelste twee partities en de partities aan beide uiteinden zijn leeg.