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

Switch-out di una partizione in SQL Server (T-SQL)

In SQL Server, il cambio di partizione consente di caricare grandi quantità di dati all'interno o all'esterno di una tabella molto rapidamente. Ciò evita di dover eseguire istruzioni di eliminazione o inserimento e può essere molto utile quando si lavora con insiemi di dati di grandi dimensioni.

Puoi usare ALTER TABLE istruzione per cambiare una partizione dentro o fuori una tabella.

Per cambiare una partizione da una tabella, il codice è questo:

ALTER TABLE Table1
SWITCH PARTITION x TO Table2

Questo cambia la partizione x da Table1 a Table2 (dove x è il numero della partizione).

Esempio

La configurazione

Prima di iniziare a cambiare, creeremo la configurazione di base. Questo sarà composto da due tabelle. Uno sarà la tabella di origine partizionata, l'altro sarà la tabella di destinazione. Creeremo anche quattro filegroup, uno per ogni partizione.

-- Create filegroups
ALTER DATABASE Test ADD FILEGROUP OrdersLatestFg1;
GO

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

ALTER DATABASE Test ADD FILEGROUP OrdersLatestFg2;
GO

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

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

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

-- Create a partition function that will result in four partitions  
CREATE PARTITION FUNCTION OrdersLatestPartitionFunction (date)  
    AS RANGE RIGHT FOR VALUES (
        '20200201', 
        '20200301',
        '20200401'
    );
GO

-- Create a partition scheme that maps the partitions to the filegroups
CREATE PARTITION SCHEME OrdersLatestPartitionScheme
    AS PARTITION OrdersLatestPartitionFunction  
    TO (
        OrdersLatestFg1,
        OrdersLatestFg2,
        OrdersLatestFg3,
        OrdersLatestFg4
        );  
GO

-- Create a partitioned table called OrdersLatest that uses the OrderDate column as the partitioning column
CREATE TABLE OrdersLatest (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL,
    CONSTRAINT PKOrdersLatest PRIMARY KEY CLUSTERED(OrderDate, OrderId)
    )  
    ON OrdersLatestPartitionScheme(OrderDate);  
GO

-- Insert data into the OrdersLatest table. 
-- This will end up in partition 3, which is the partition we will switch out to the OrdersMarch table.
INSERT INTO OrdersLatest(OrderDate, OrderDesc) VALUES
    ('20200302', 'Cat food'),
    ('20200315', 'Water bowl'),
    ('20200318', 'Saddle for camel'),
    ('20200321', 'Dog biscuits'),
    ('20200328', 'Bigfoot shoes');
GO

-- Create a table that contains the data that we will be switching out to.  
-- Note that the filegroup matches the filegroup of the partition that we will switch out of.
CREATE TABLE OrdersMarch (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL,
    CONSTRAINT PKOrdersMarch PRIMARY KEY CLUSTERED(OrderDate, OrderId)
    )
    ON OrdersLatestFg3;
GO

-- Check how many rows are in each table
SELECT COUNT(*) AS OrdersLatest
FROM OrdersLatest;

SELECT COUNT(*) AS OrdersMarch 
FROM OrdersMarch;

Risultato:

+----------------+
| OrdersLatest   |
|----------------|
| 5              |
+----------------+

+---------------+
| OrdersMarch   |
|---------------|
| 0             |
+---------------+

Così com'è attualmente, abbiamo cinque righe in OrdersLatest table, che è la nostra tabella partizionata.

Tutte e cinque le righe dovrebbero trovarsi nella partizione 3. Verifichiamolo.

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('OrdersLatest')
ORDER BY [Partition];

Risultato:

+-------------+-----------------+--------+
| Partition   | Filegroup       | Rows   |
|-------------+-----------------+--------|
| 1           | OrdersLatestFg1 | 0      |
| 2           | OrdersLatestFg2 | 0      |
| 3           | OrdersLatestFg3 | 5      |
| 4           | OrdersLatestFg4 | 0      |
+-------------+-----------------+--------+

Sì, quindi possiamo vedere che tutte e cinque le righe sono nella partizione 3. Possiamo anche vedere che la partizione 3 è mappata su OrdersLatestFg3 filegroup. Affinché il nostro "switch out" abbia successo, dobbiamo assicurarci che la nostra tabella di destinazione utilizzi questo filegroup. Fortunatamente, il nostro codice sopra fa esattamente questo. Abbiamo usato ON OrdersLatestFg3 durante la creazione della tabella per specificare che la tabella deve essere creata su quel filegroup.

Spegni

OK, quindi tutto è pronto per essere spento. Facciamolo.

ALTER TABLE OrdersLatest
SWITCH PARTITION 3 TO OrdersMarch;

Risultato:

Commands completed successfully.

Eccellente. Il nostro passaggio ha funzionato.

Controlliamo di nuovo il numero di righe in ogni tabella.

SELECT COUNT(*) AS OrdersLatest
FROM OrdersLatest;

SELECT COUNT(*) AS OrdersMarch 
FROM OrdersMarch;

Risultato:

+----------------+
| OrdersLatest   |
|----------------|
| 0              |
+----------------+

+---------------+
| OrdersMarch   |
|---------------|
| 5             |
+---------------+

Quindi possiamo vedere che i dati sono stati spostati da OrdersLatest tabella a OrdersMarch tabella.

Controlliamo le informazioni sulla partizione per OrdersLatest .

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('OrdersLatest')
ORDER BY [Partition];

Risultato:

+-------------+-----------------+--------+
| Partition   | Filegroup       | Rows   |
|-------------+-----------------+--------|
| 1           | OrdersLatestFg1 | 0      |
| 2           | OrdersLatestFg2 | 0      |
| 3           | OrdersLatestFg3 | 0      |
| 4           | OrdersLatestFg4 | 0      |
+-------------+-----------------+--------+

Come previsto, il OrdersLatestFg3 la partizione è ora vuota. Questo perché è stato disattivato.

Controlliamo le informazioni sulla partizione per OrdersMarch tabella.

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('OrdersMarch')
ORDER BY [Partition];

Risultato:

+-------------+-----------------+--------+
| Partition   | Filegroup       | Rows   |
|-------------+-----------------+--------|
| 1           | OrdersLatestFg3 | 5      |
+-------------+-----------------+--------+

Anche in questo caso, come previsto, la tabella OrdersMarch contiene cinque righe. Sono archiviati nella partizione 1 (l'unica partizione) su OrdersLatest3 filegroup.

Accensione

Per informazioni su come attivare una partizione, vedere Switch-in di una partizione in SQL Server.