sql >> Base de Datos >  >> RDS >> Sqlserver

Crear una tabla particionada en SQL Server (T-SQL)

SQL Server admite tablas e índices particionados. Cuando se particiona una tabla o índice particionado, sus datos se dividen en unidades que se pueden distribuir en más de un grupo de archivos.

Por lo tanto, para crear una tabla particionada en SQL Server, primero debe crear los grupos de archivos que contendrán cada partición. También necesita crear una función de partición y un esquema de partición.

Entonces es así:

  1. Crear grupo/s de archivos
  2. Crear una función de partición
  3. Crear un esquema de partición
  4. Crear la tabla particionada

A continuación se muestra un ejemplo del uso de estos pasos para crear una tabla con cuatro particiones.

Crear grupos de archivos

Primero, agregamos cuatro grupos de archivos a la base de datos llamada Prueba y luego especifique el archivo físico para cada uno de esos grupos de archivos.

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  

Deberá cambiar este código, según sus requisitos. También deberá cambiar las rutas de los archivos para que se adapten a su entorno. Por ejemplo, si está en Windows, su ruta podría parecerse más a D:\mssql\data\MoviesFg4dat.ndf .

Además, si necesita más particiones, agregue más grupos de archivos aquí. Por el contrario, si necesita menos particiones, especifique aquí menos grupos de archivos.

Crear una función de partición

A continuación, creamos una función de partición llamada MoviesPartitionFunction eso dividirá la tabla en cuatro particiones.

CREATE PARTITION FUNCTION MoviesPartitionFunction (int)  
    AS RANGE LEFT FOR VALUES (1, 100, 1000);
GO

El int parte especifica el tipo de datos de la columna utilizada para la partición.

Todos los tipos de datos son válidos para usar como columnas de partición, excepto texto , ntext , imagen , xml , marca de tiempo , varchar(máximo) , nvarchar(máximo) , varbinario(máximo) , tipos de datos de alias o tipos de datos definidos por el usuario de CLR.

Aquí, utilizo tres valores límite (1, 100 y 1000 ) para especificar cuatro particiones. Estos valores límite deben coincidir o ser implícitamente convertibles al tipo de datos especificado entre paréntesis después del nombre de la función de partición.

Dados estos valores límite y el hecho de que especifiqué un RANGE LEFT partición, las cuatro particiones tendrán valores como se especifica en la siguiente tabla.

Partición Valores
1 <= 1
2 1 Y <= 100
3 100 Y <=1000
4 1000

Si hubiera especificado un RANGE RIGHT partición, el desglose sería ligeramente diferente, como se describe en la siguiente tabla.

Partición Valores
1 1
2 >= 1 Y < 100
3 >= 100 Y < 1000
4 >= 1000

El mismo concepto se aplica si la columna de partición usa otros tipos de datos, como valores de fecha/hora.

Crear un esquema de partición

A continuación, debemos crear un esquema de partición.

Un esquema de partición asigna las particiones de una tabla o índice particionado a los nuevos grupos de archivos.

En nuestro caso, el código se verá así:

CREATE PARTITION SCHEME MoviesPartitionScheme  
    AS PARTITION MoviesPartitionFunction  
    TO (MoviesFg1, MoviesFg2, MoviesFg3, MoviesFg4);  
GO

Observe que hacemos referencia a la función de partición que creamos en el paso anterior. También hacemos referencia a los grupos de archivos que creamos en el primer paso.

Crear la tabla particionada

Finalmente podemos crear la tabla particionada.

CREATE TABLE Movies (
    MovieId int IDENTITY PRIMARY KEY, 
    MovieName varchar(60)
    )  
    ON MoviesPartitionScheme (MovieId);  
GO

La única diferencia entre esto y la creación de una tabla sin particiones es que al crear una tabla con particiones, usamos ON argumento para especificar un esquema de partición a utilizar. En nuestro caso, especificamos el esquema de partición que creamos en el paso anterior y especificamos el MovieId columna como la columna de partición.

Notarás que el MovieId la columna tiene un tipo de datos de int , que coincide con los valores límite que especificamos al crear la función de partición.

Tenga en cuenta que si usa una columna calculada en una función de partición, debe marcarse explícitamente como PERSISTED .

Compruebe la función de partición

Puede usar sys.partition_functions vista para devolver todas las funciones de partición.

SELECT * FROM sys.partition_functions;

Resultado (usando salida vertical):

name                    | MoviesPartitionFunction
function_id             | 65536
type                    | R 
type_desc               | RANGE
fanout                  | 4
boundary_value_on_right | 0
is_system               | 0
create_date             | 2020-10-10 05:37:41.330
modify_date             | 2020-10-10 05:37:41.330

Comprobar el esquema de partición

Puede usar sys.partition_schemes para comprobar el esquema de partición.

SELECT * FROM sys.partition_schemes;

Resultado (usando salida vertical):

name          | MoviesPartitionScheme
data_space_id | 65601
type          | PS
type_desc     | PARTITION_SCHEME
is_default    | 0
is_system     | 0
function_id   | 65536

Alternativamente, puede usar la siguiente consulta para obtener otros detalles, como el esquema, la tabla, el índice, etc.

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;

Resultado (usando salida vertical):

Schema           | dbo
Object           | Movies
Index            | PK__Movies__4BD2941A0ED85ACA
Partition Scheme | MoviesPartitionScheme

Comprobar la tabla particionada

Puede ejecutar sys.dm_db_partition_stats vista para devolver información de recuento de páginas y filas para cada partición en la base de datos actual.

Pero ejecutar eso antes de insertar cualquier dato en la tabla dará como resultado que la mayoría de las estadísticas sean cero.

Así que voy a insertar datos primero.

INSERT INTO Movies
SELECT name FROM OtherDb.dbo.Movies;

Resultado:

(4079 rows affected)

Podemos ver que se insertaron 4079 filas.

Ahora consultemos el sys.dm_db_partition_stats ver.

SELECT *
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');

Resultado:

+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+
| partition_id      | object_id   | index_id   | partition_number   | 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   | reserved_page_count   | row_count   |
|-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------|
| 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        |
+-------------------+-------------+------------+--------------------+--------------------------+--------------------------+------------------------------+-----------------------+---------------------------+--------------------------------+------------------------------------+-------------------+-----------------------+-------------+

Esta vista muestra muchas columnas, así que reduzcamos las columnas a solo un par.

SELECT 
    partition_number,
    row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');

Resultado:

+--------------------+-------------+
| partition_number   | row_count   |
|--------------------+-------------|
| 1                  | 1           |
| 2                  | 99          |
| 3                  | 900         |
| 4                  | 3079        |
+--------------------+-------------+

Podemos ver cómo se asignan las filas en las particiones. Se asignan exactamente como especificamos en la función de partición. Las filas suman 4079, que es exactamente cuántas filas insertamos.

Sin embargo, vale la pena señalar que la documentación de Microsoft en realidad establece que esta columna es solo una aproximación cuenta de las filas en cada partición.

Buenas prácticas

Microsoft recomienda que siempre mantengamos particiones vacías en ambos extremos del rango de partición.

Esto es en caso de que necesite dividir o fusionar las particiones en el futuro.

El motivo de esta recomendación es garantizar que la división de partición y la fusión de partición no incurran en ningún movimiento de datos inesperado.

Por lo tanto, dados los datos de mi ejemplo, podría cambiar la función de partición para que se vea así:

CREATE PARTITION FUNCTION MoviesPartitionFunction (int)  
    AS RANGE LEFT FOR VALUES (-1, 100, 10000);
GO

O si anticipo más de 10 000 filas, podría usar un número mayor (o crear más particiones).

Si tuviera que volver a crear todos los pasos para crear mi tabla particionada, las estadísticas de mi partición se verían así:

SELECT 
    partition_number,
    row_count
FROM sys.dm_db_partition_stats
WHERE object_id = OBJECT_ID('dbo.Movies');

Resultado:

+--------------------+-------------+
| partition_number   | row_count   |
|--------------------+-------------|
| 1                  | 0           |
| 2                  | 100         |
| 3                  | 3979        |
| 4                  | 0           |
+--------------------+-------------+

Ahora mis datos están concentrados en las dos particiones del medio, y las particiones en ambos extremos están vacías.