sql >> Databasteknik >  >> RDS >> Sqlserver

Byt ut en partition i SQL Server (T-SQL)

I SQL Server låter partitionsbyte dig ladda stora mängder data in eller ut ur en tabell mycket snabbt. Detta sparar dig från att behöva köra delete eller infoga uttalanden, och kan vara mycket användbart när du arbetar med stora datamängder.

Du kan använda ALTER TABLE uttalande för att byta en partition in eller ut från en tabell.

För att byta ut en partition från en tabell går koden så här:

ALTER TABLE Table1
SWITCH PARTITION x TO Table2

Detta byter partition x från Table1 till Table2 (där x är partitionsnumret).

Exempel

Inställningen

Innan vi börjar byta ut skapar vi grundinställningen. Detta kommer att bestå av två bord. Den ena kommer att vara den partitionerade källtabellen, den andra kommer att vara destinationstabellen. Vi kommer också att skapa fyra filgrupper - en för varje partition.

-- 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;

Resultat:

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

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

Så som det ser ut för närvarande har vi fem rader i OrdersLatest tabell, som är vår partitionerade tabell.

Alla fem raderna bör vara i partition 3. Låt oss kontrollera det.

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];

Resultat:

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

Ja, så vi kan se att alla fem raderna är i partition 3. Vi kan också se att partition 3 är mappad till OrdersLatestFg3 filgrupp. För att vårt "byte" ska bli framgångsrikt måste vi se till att vår destinationstabell använder denna filgrupp. Lyckligtvis gör vår ovanstående kod precis det. Vi använde ON OrdersLatestFg3 när du skapar tabellen för att ange att tabellen ska skapas på den filgruppen.

Stäng av

OK, så allt är redo att bytas ut. Låt oss göra det.

ALTER TABLE OrdersLatest
SWITCH PARTITION 3 TO OrdersMarch;

Resultat:

Commands completed successfully.

Excellent. Vår byte fungerade.

Låt oss kontrollera antalet rader i varje tabell igen.

SELECT COUNT(*) AS OrdersLatest
FROM OrdersLatest;

SELECT COUNT(*) AS OrdersMarch 
FROM OrdersMarch;

Resultat:

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

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

Så vi kan se att data har flyttats från OrdersLatest tabell till OrdersMarch bord.

Låt oss kontrollera partitionsinformationen för 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];

Resultat:

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

Som förväntat, OrdersLatestFg3 partitionen är nu tom. Detta beror på att den har stängts av.

Låt oss kontrollera partitionsinformationen för OrdersMarch bord.

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];

Resultat:

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

Återigen som förväntat innehåller OrdersMarch-tabellen fem rader. De lagras i partition 1 (den enda partitionen) på OrdersLatest3 filgrupp.

Slå in

Se Byta in en partition i SQL Server för hur du byter in en partition.


  1. 4 sätt att få en vys definition med Transact-SQL

  2. Vad är maxstorleken på VARCHAR2 i PL/SQL och SQL?

  3. MySQL-variabelt format för en NOT IN-lista med värden

  4. Ändra datumformatet för den aktuella sessionen i SQL Server