Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come mappare più partizioni su un singolo filegroup in SQL Server (T-SQL)

Se hai familiarità con la creazione di tabelle partizionate in SQL Server, potresti essere abituato a creare un filegroup separato per ogni partizione. Questo ha i suoi vantaggi e potrebbe benissimo essere il metodo che sceglieresti nella maggior parte degli scenari.

Tuttavia, hai anche la possibilità di mappare più partizioni su un singolo filegroup.

In questo articolo condivido due esempi di mappatura di più partizioni su un singolo filegroup.

  • Esempio 1 mappe tutte partizioni in un singolo filegroup.
  • L'esempio 2 associa alcune partizioni a un filegroup e alcune a un altro.

Esempio 1:mappare tutte le partizioni su un singolo filegroup

Per mappare tutte le partizioni su un singolo filegroup, utilizzare l'argomento ALL. Specifica che tutte le partizioni vengono mappate al filegroup specificato o al filegroup primario se [PRIMARY] è specificato.

Nota che quando ALL è specificato, è possibile specificare un solo filegroup.

-- Create one filegroup
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg1;
GO

ALTER DATABASE Test   
ADD FILE   
(  
    NAME = OrdersNewFg1dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg1dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB  
)  
TO FILEGROUP OrdersNewFg1;
GO

-- Create a partition function that will result in twelve partitions  
CREATE PARTITION FUNCTION OrdersNewPartitionFunction (date)  
    AS RANGE RIGHT FOR VALUES (
        '20200201', 
        '20200301',
        '20200401', 
        '20200501',
        '20200601',
        '20200701',
        '20200801',
        '20200901',
        '20201001',
        '20201101',
        '20201201'
    );
GO

-- Create a partition scheme that maps all partitions to the OrdersNewFg1 filegroup
CREATE PARTITION SCHEME OrdersNewPartitionScheme
    AS PARTITION OrdersNewPartitionFunction  
    ALL TO (OrdersNewFg1);  
GO

-- Create a partitioned table
CREATE TABLE OrdersNew (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL
    )  
    ON OrdersNewPartitionScheme (OrderDate);  
GO

Qui, ho fatto quanto segue:

  • Creato un filegroup e file associato
  • Creata una funzione di partizione
  • Creato uno schema di partizione
  • Creata una tabella che utilizza quello schema di partizione

La parte fondamentale è l'ultima riga di CREATE PARTITION SCHEME dichiarazione. Nello specifico, è il ALL parola chiave che associa tutte le partizioni al filegroup specificato.

Se li stavi mappando su più filegroup, ometteresti ALL , quindi avere un elenco di filegroup separato da virgole anziché uno solo.

Controlla la mappatura

Possiamo usare la seguente query per verificare che ogni partizione sia mappata sullo stesso filegroup.

SELECT 
    p.partition_number AS [Partition], 
    fg.name AS [Filegroup], 
    p.Rows
FROM sys.partitions p
    INNER JOIN sys.allocation_units au
    ON au.container_id = p.hobt_id
    INNER JOIN sys.filegroups fg
    ON fg.data_space_id = au.data_space_id
WHERE p.object_id = OBJECT_ID('OrdersNew');

Risultato:

+-------------+--------------+--------+
| Partition   | Filegroup    | Rows   |
|-------------+--------------+--------|
| 1           | OrdersNewFg1 | 0      |
| 2           | OrdersNewFg1 | 0      |
| 3           | OrdersNewFg1 | 0      |
| 4           | OrdersNewFg1 | 0      |
| 5           | OrdersNewFg1 | 0      |
| 6           | OrdersNewFg1 | 0      |
| 7           | OrdersNewFg1 | 0      |
| 8           | OrdersNewFg1 | 0      |
| 9           | OrdersNewFg1 | 0      |
| 10          | OrdersNewFg1 | 0      |
| 11          | OrdersNewFg1 | 0      |
| 12          | OrdersNewFg1 | 0      |
+-------------+--------------+--------+

Questa query ci mostra anche quante righe ci sono in ogni partizione. Non abbiamo inserito alcun dato quindi sono tutti zero.

Esempio 2:mappare alcune partizioni su un singolo filegroup

Questo esempio è quasi identico all'esempio precedente, tranne per il fatto che mappiamo le dodici partizioni su due filegroup separati.

In questo caso, omettiamo ALL argomento, perché è possibile specificare un solo filegroup quando ALL è specificato.

-- Create two filegroups
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg1;
GO

ALTER DATABASE Test   
ADD FILE   
(  
    NAME = OrdersNewFg1dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg1dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB  
)  
TO FILEGROUP OrdersNewFg1;
GO

ALTER DATABASE Test ADD FILEGROUP OrdersNewFg2;
GO

ALTER DATABASE Test   
ADD FILE   
(  
    NAME = OrdersNewFg2dat,  
    FILENAME = '/var/opt/mssql/data/OrdersNewFg2dat.ndf',  
    SIZE = 5MB,  
    MAXSIZE = 100MB,  
    FILEGROWTH = 5MB  
)  
TO FILEGROUP OrdersNewFg2;
GO

-- Create a partition function that will result in twelve partitions  
CREATE PARTITION FUNCTION OrdersNewPartitionFunction (date)  
    AS RANGE RIGHT FOR VALUES (
        '20200201', 
        '20200301',
        '20200401', 
        '20200501',
        '20200601',
        '20200701',
        '20200801',
        '20200901',
        '20201001',
        '20201101',
        '20201201'
    );
GO

-- Create a partition scheme that maps all partitions to the OrdersNewFg1 filegroup
CREATE PARTITION SCHEME OrdersNewPartitionScheme
    AS PARTITION OrdersNewPartitionFunction  
    TO (
        OrdersNewFg1,
        OrdersNewFg1,
        OrdersNewFg1,
        OrdersNewFg1,
        OrdersNewFg1,
        OrdersNewFg1,
        OrdersNewFg2,
        OrdersNewFg2,
        OrdersNewFg2,
        OrdersNewFg2,
        OrdersNewFg2,
        OrdersNewFg2
        );  
GO

-- Create a partitioned table
CREATE TABLE OrdersNew (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL
    )  
    ON OrdersNewPartitionScheme (OrderDate);  
GO

Controlla la mappatura

Vediamo come vengono mappate le partizioni sui filegroup.

SELECT 
    p.partition_number AS [Partition], 
    fg.name AS [Filegroup], 
    p.Rows
FROM sys.partitions p
    INNER JOIN sys.allocation_units au
    ON au.container_id = p.hobt_id
    INNER JOIN sys.filegroups fg
    ON fg.data_space_id = au.data_space_id
WHERE p.object_id = OBJECT_ID('OrdersNew');

Risultato:

+-------------+--------------+--------+
| Partition   | Filegroup    | Rows   |
|-------------+--------------+--------|
| 1           | OrdersNewFg1 | 0      |
| 2           | OrdersNewFg1 | 0      |
| 3           | OrdersNewFg1 | 0      |
| 4           | OrdersNewFg1 | 0      |
| 5           | OrdersNewFg1 | 0      |
| 6           | OrdersNewFg1 | 0      |
| 7           | OrdersNewFg2 | 0      |
| 8           | OrdersNewFg2 | 0      |
| 9           | OrdersNewFg2 | 0      |
| 10          | OrdersNewFg2 | 0      |
| 11          | OrdersNewFg2 | 0      |
| 12          | OrdersNewFg2 | 0      |
+-------------+--------------+--------+

Come previsto, le prime sei partizioni vengono mappate sul primo filegroup e le restanti sul secondo.