Ante todo agradecer la enorme cantidad de correos recibidos con salutaciones, agradecimientos, consultas, correcciones etc. Es un placer estar en contacto con uds y sepan disculpar si no les contesto a tiempo.
Ok dicho esto y deseándoles un feliz 2014 vamos al tema que nos convoca.
Ya hemos visto
1) Como particionar tablas en 5 pasos http://gherrerasqlserver.blogspot.com.ar/2013/05/particionar-tablas-en-5-pasos.html
2) Como mantener las particiones creadas (Split y Merge) http://gherrerasqlserver.blogspot.com.ar/2013/05/mantener-particiones-de-tablas-split-y.html
Pues bien habiendo recibido un correo de un lector del blog que me hablaba del enorme tiempo que le insumía el borrar vieja data de una partición, en oportunidad del pase a histórico de la data más vieja de la partición. Me di cuenta que nunca les hablé de cómo llevar adelante esta tarea rápidamente a través de Switch Partition.
Vamos a poner manos a la obra.
Supongamos que tenemos este esquema de partición con los datos de nuestras ventas de los años 2012 y 2013
CREATE PARTITION FUNCTION
[PF_Ventas](datetime)
AS RANGE LEFT
FOR VALUES ('2012-06-30 23:59:59.000',
'2012-12-31
23:59:59.000',
'2013-06-30
23:59:59.000',
'2013-12-31
23:59:59.000')
GO
Pues bien amigos... ok para pasar a una tabla histórica los datos del primer semestre del 2012.
En lo primero que pensaríamos sería en hacer un insert de los datos de la tabla de ventas en una tabla histórica y luego borrar de la tabla ventas los registros
INSERT INTO ventas_old
select * from ventas
where fecha < '2012-06-30 23:59:59.000'
Delete from tabla_ventas
where fecha < '2012-06-30
23:59:59.000'
Para luego mergear la partición 1 y 2 ver merge y split en 2)
ERROR !!!
Pero por qué?
Estaríamos generando una enorme carga en nuestro servidor borrando millones de registros, bloqueando la tabla y generando muy posiblemente un crecimiento desmesurado de nuestro LOG...
SOLUCION
Microsoft pensó en nosotros y nos pone a disposición una forma mucho menos costosa de hacerlo a través del comando SWITCH PARTITION
Veamos:
Paso 1) Creamos una tabla temporal con idéntica estructura a la tabla en la que queremos borrar la data ( en nuestro ejemplo la tabla ventas )
La tabla temporal debe estar creada en el mismo filegroup donde se almacenan los registros correspondientes a la partición a borrar.
CREATE TABLE [dbo].[temp_ventas](
La tabla temporal debe estar creada en el mismo filegroup donde se almacenan los registros correspondientes a la partición a borrar.
CREATE TABLE [dbo].[temp_ventas](
[fecha] [datetime] NULL,
[codigo] [integer] NULL,
[Descripción]
[varchar](100) NULL)
Debemos crear un índice cluster sobre la tabla temporal idéntico al definido en la tabla madre pero sobre el filegroup donde creamos la tabla temporal.
Aquí es necesario detenernos un instante para evitar mensajes de error en el próximo paso y tener en cuenta que:
Si todos los índices de la tabla particionada están "alineados"(es decir definidos sobre la partición), no tendremos que hacer ninguna acción, sólo i hacia el "paso 2"
Si por el contrario, los índice no están alineados..debemos de crearlos tal cual están definidos en la tabla particionada, sobre la tabla temporal.
Paso 2) Switcheamos la particion hacia la tabla temporal creada. Esto, por simple movimiento de metadata generará la transeferencia de los datos que queremos pasar a histórico hacia la tabla temporal de un sorprendemente rápido. Sin costos para el sistema.
ALTER TABLE Ventas
SWITCH PARTITION
1 TO Temp_Ventas
PASO 3) Ahora si, con la data a pasar a histórico en la tabla temporal podremos
3.1) Insertar rápidamente esta data en nuestra tabla histórica ventas_old desde nuestra tabla temporal
3.2) Dropear nuestra tabla temporal
3.3) Hacer ahora si el merge y borrar el datafile y el filegroup viejo (ver Mantenimiento de Particiones en este mismo blog)
Y bien amigos... eso es todo por ahora, sencillo y práctico.
Los animo a ponerlo en práctica y como siempre a preguntarme si encuentran dificultades.
Saludos!!!