Implementación de Particionamiento Horizontal con Vistas Particionadas en SQL Server

En este artículo exploraremos cómo implementar el particionamiento horizontal en SQL Server utilizando vistas particionadas. Este enfoque nos permite distribuir datos grandes en múltiples tablas físicas mientras mantenemos una vista lógica unificada para consultas.

Primero, crearemos una base de datos de demostración:

USE [BaseDemo]
GO

-- Crear tablas con estructura idéntica, sin autoincremento en el campo id
-- DROP TABLE [TablaParticion01],[TablaParticion02],[TablaParticion03]
CREATE TABLE [dbo].[TablaParticion01](
    [codigo] [int] NOT NULL,
    [fecha_registro] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TablaParticion02](
    [codigo] [int] NOT NULL,
    [fecha_registro] [datetime] NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[TablaParticion03](
    [codigo] [int] NOT NULL,
    [fecha_registro] [datetime] NULL
) ON [PRIMARY]
GO

-- Establecer rangos de valores para cada tabla mediante restricciones CHECK
ALTER TABLE [dbo].[TablaParticion01] WITH CHECK ADD CONSTRAINT [CK_TablaParticion01_codigo] CHECK ([codigo] BETWEEN 0 AND 99999 )
GO
ALTER TABLE [dbo].[TablaParticion02] WITH CHECK ADD CONSTRAINT [CK_TablaParticion02_codigo] CHECK ([codigo] BETWEEN 100000 AND 199999 )
GO
ALTER TABLE [dbo].[TablaParticion03] WITH CHECK ADD CONSTRAINT [CK_TablaParticion03_codigo] CHECK ([codigo] BETWEEN 200000 Y 299999 )
GO

-- Crear índices agrupados en la columna de particionamiento para optimizar el acceso
ALTER TABLE [dbo].[TablaParticion01] ADD CONSTRAINT [PK_TablaParticion01_codigo] PRIMARY KEY CLUSTERED ([codigo] ASC)
GO
ALTER TABLE [dbo].[TablaParticion02] ADD CONSTRAINT [PK_TablaParticion02_codigo] PRIMARY KEY CLUSTERED ([codigo] ASC)
GO
ALTER TABLE [dbo].[TablaParticion03] ADD CONSTRAINT [PK_TablaParticion03_codigo] PRIMARY KEY CLUSTERED ([codigo] ASC)
GO

Ahora crearemos la vista particionada que combina todas las tablas:

-- DROP VIEW [dbo].[VistaParticionada]
CREATE VIEW [dbo].[VistaParticionada]
AS
SELECT [codigo],[fecha_registro] FROM [dbo].[TablaParticion01]
UNION ALL
SELECT [codigo],[fecha_registro] FROM [dbo].[TablaParticion02]
UNION ALL
SELECT [codigo],[fecha_registro] FROM [dbo].[TablaParticion03]
GO

-- Insertar datos de prueba desde una base de datos de ejemplo
INSERT INTO [VistaParticionada]([codigo],[fecha_registro])
SELECT SalesOrderDetailID,ModifiedDate FROM AdventureWorks2012.Sales.SalesOrderDetail
GO

-- Verificar la distribución de datos
SELECT COUNT(*) FROM [dbo].[VistaParticionada]
SELECT COUNT(*) FROM [dbo].[TablaParticion01]
SELECT COUNT(*) FROM [dbo].[TablaParticion02]
SELECT COUNT(*) FROM [dbo].[TablaParticion03]

Al realizar consultas sobre la vista, SQL Server optimiza el acceso solo a las tablas relevantes:

-- Consulta con valor fuera de rango (no existe)
SELECT * FROM [dbo].[VistaParticionada] WHERE codigo = 0
-- Consulta con valor en el rango de la primera tabla
SELECT * FROM [dbo].[VistaParticionada] WHERE codigo = 3000
-- Consulta con valor fuera de todos los rangos definidos
SELECT * FROM [dbo].[VistaParticionada] WHERE codigo = 300000

Como se observa, las consultas con valores dentro de los rangos definidos acceden solo a las tablas correspondientes, mientras que las consultas fuera de rango realizan un escaneo constante sin lectura de datos, mejorando el rendimiento.

Ahora analicemos el comportamiento al actualizar datos a través de la vista:

BEGIN TRAN
    UPDATE [dbo].[VistaParticionada] SET fecha_registro = '2005-11-01' WHERE codigo = 3000
    
    -- Verificar los bloqueos activos
    select CASE resource_type WHEN 'OBJECT' THEN OBJECT_NAME(resource_associated_entity_id) ELSE '' END AS [objeto]
    ,resource_type,resource_description,request_mode,request_status,request_type
    from sys.dm_tran_locks where resource_database_id=DB_ID() and request_session_id=@@SPID  
COMMIT TRAN

La actualización se dirige solo a la tabla que contiene el registro (TablaParticion01), pero se aplican bloqueos de Intención de Exclusión (IX) a las otras tablas, lo que puede afectar el rendimiento en entornos de alta concurrencia.

En los planes de ejecución, las tablas que no cumplen con las condiciones de filtro realizan escaneos constantes, lo que añade overhead aunque no lean datos.

Etiquetas: SQL Server particionamiento de datos vistas particionadas optimización de consultas gestión de bases de datos

Publicado el 6-9 16:31