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

Commutare una partizione in SQL Server (T-SQL)

In SQL Server è possibile cambiare partizioni dentro e fuori una tabella partizionata.

Puoi farlo con ALTER TABLE dichiarazione. Fondamentalmente, funziona così:

ALTER TABLE OldTable
SWITCH TO NewTable PARTITION x

Questo cambia la partizione per OldTable nella partizione x di NewTable (dove x è il numero della partizione).

Esempio

Prima di iniziare a entrare, impostiamo due tabelle. Uno (chiamato OrdersOld ) conterrà i dati che vogliamo "passare" all'altra tabella (denominata OrdersNew ).

Partizioneremo OrdersNew in quattro partizioni.

-- Create 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
ALTER DATABASE Test ADD FILEGROUP OrdersNewFg3;
GO

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

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

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

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

-- Create a table that contains the data that we will be switching in.  
-- Note that the filegroup matches the filegroup of the partition that we will switch in to.
-- Include CHECK constraint to restrict data to the range specified in the switch-in partition
CREATE TABLE OrdersOld (
    OrderDate date NOT NULL,
    OrderId int IDENTITY NOT NULL,
    OrderDesc varchar(255) NOT NULL,
    CONSTRAINT chkDate CHECK (OrderDate >= '20200301' AND OrderDate < '20200401'),
    CONSTRAINT PKOrdersOld PRIMARY KEY CLUSTERED(OrderDate, OrderId)
    )
    ON OrdersNewFg3;
GO

-- Insert data into the OrdersOld table. This is the data we will be switching in to the OrdersNew table.
INSERT INTO OrdersOld(OrderDate, OrderDesc) VALUES
    ('20200302', 'Cat food'),
    ('20200315', 'Water bowl'),
    ('20200318', 'Saddle for camel'),
    ('20200321', 'Dog biscuits'),
    ('20200328', 'Bigfoot shoes');
GO

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

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

SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;

Risultato:

+-------------+
| OrdersOld   |
|-------------|
| 5           |
+-------------+

+-------------+
| OrdersNew   |
|-------------|
| 0           |
+-------------+

Così com'è adesso, OrdersOld contiene 5 righe e OrdersNew è vuoto.

È ora di inserire i dati.

ALTER TABLE OrdersOld
SWITCH TO OrdersNew PARTITION 3;

Risultato:

Commands completed successfully.

I dati sono stati ora trasferiti correttamente alla partizione 3 della tabella di destinazione.

Controlliamo di nuovo entrambe le tabelle.

SELECT COUNT(*) AS OrdersOld 
FROM OrdersOld;

SELECT COUNT(*) AS OrdersNew
FROM OrdersNew;

Risultato:

+-------------+
| OrdersOld   |
|-------------|
| 0           |
+-------------+

+-------------+
| OrdersNew   |
|-------------|
| 5           |
+-------------+

Questa volta OrdersOld è vuoto e OrdersNew contiene 5 righe.

Possiamo anche eseguire la seguente query per verificare la partizione effettiva in cui si trovano i dati.

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

Risultato:

+-------------+--------------+--------+
| Partition   | Filegroup    | Rows   |
|-------------+--------------+--------|
| 1           | OrdersNewFg1 | 0      |
| 2           | OrdersNewFg2 | 0      |
| 3           | OrdersNewFg3 | 5      |
| 4           | OrdersNewFg4 | 0      |
+-------------+--------------+--------+

Come previsto, tutte e 5 le righe sono allocate alla partizione 3, in OrdersNewFg3 filegroup.

Errori comuni

Errore 4982

Nel mio esempio sopra, noterai che ho creato un CHECK vincolo durante la creazione di OrdersOld tabella.

Se viene visualizzato il messaggio di errore 4982 (ALTER TABLE SWITCH statement failed... ), è possibile che tu non abbia creato un CHECK vincolo sulla tabella di origine.

Oppure potrebbe essere che hai creato un CHECK vincolo, ma non applica i valori tra l'intervallo della partizione di commutazione.

È necessario assicurarsi che i valori di commutazione rientrino nell'intervallo definito dalla partizione e SQL Server cercherà un CHECK vincolo sulla tabella di origine che lo verifica.

Errore 4939

Un altro errore comune è l'errore 4939 (ALTER TABLE SWITCH statement failed... ).

Se ricevi questo errore, probabilmente è perché stai tentando di passare a una partizione che utilizza un filegroup diverso dalla tabella di origine.

Uno dei requisiti per cambiare partizione è che sia la tabella o partizione di origine, sia la tabella o partizione di destinazione, devono trovarsi nello stesso filegroup.

Per correggere questo errore, assicurati che la tabella di origine utilizzi lo stesso filegroup della partizione di destinazione.

Spegnimento

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