Problema con tablas particionadas

15/12/2004 - 16:25 por e.lorenzo | Informe spam
Hola a todos,

tenemos una aplicación que, por el volumen de información que maneja, nos
obliga a crear particiones por meses en 5 tablas del modelo. De esta
forma, mantendremos un histórico de 12 meses que iremos rotando. La idea
no es particionar para poder ejecutar las consultas en paralelo, sino por
facilitar el borrado y mantenimiento.

Cuando empezamos a analizar cómo crear estas particiones en SQL SERVER (la
aplicación también corre con Oracle y ahí hemos podido implementarlas sin
problemas), empezó nuestro "calvario".

Investigando, descubrimos que debíamos crear 12 tablas por cada una de las
que deseamos particionar y, en cada una de las 12, añadir una CHECK que
indique qué mes es el que contiene. A continuación, se crea una vista cuya
definición es un UNION ALL de cada una de las 12 tablas. Hasta aquí bien.

El problema es que una de las 5 tablas que deseamos particionar no tiene
clave primaria. Las otras cuatro sí la tienen y, además, el campo por el
que particionamos pertenece a ella.

La tabla no tiene clave primaria, porque intervienen 22 campos y no es
relevante, al controlar nosotros las inserciones. Tan sólo creamos dos
índices no únicos para optimizar las consultas que se realizan sobre ella.

Al ir a crear una partición, en SQL Server te exige que el campo sobre el
que indicas la condición forme parte de la clave primaria. Por tanto, como
no es viable crear la clave primaria con 22 campos (aparte de que el
límite son 15, el índice ocupa más que la tabla) y no queremos crear un
campo que guarde el valor de la concatenación de todos, nos planteamos
crear una PK con la fecha y un secuencial (IDENTITY). Pero nos encontramos
que en tablas particionadas no se permite usar esta funcionalidad.

Decidimos abordar el problema con un trigger que informara este valor
secuencial y nos permitiera simular la PK, pero el problema es que las
inserciones se hacen mediante INSERT...SELECT (con más de un registro) y
no éramos capaces de que le asignara un número diferente a cada registro,
sino el mismo a cada uno de los obtenidos en el SELECT.

¿Nos puede indicar alguien si hay alguna forma más sencilla de gestionar
las particiones o, si hasta ahora no hemos hecho nada mal, cómo podemos
crear una clave primaria "en tiempo de ejecución" con un INSERT..SELECT?
Por ejemplo, algo similar a la función ROWNUM de Oracle concatenada con un
timestamp. ¿Hay algo equivalente en SQL SERVER?

Contar con el agravante de que tenemos una aplicación ya rodada y con dos
gestores y queremos tratar de tener que montar un lío tremendo sólo por
SQL Server.

Muchas gracias por anticipado.

Un saludo

Preguntas similare

Leer las respuestas

#1 Salvador Ramos
15/12/2004 - 16:46 | Informe spam
Otra altenativa sería tener una sola tabla en la versión de SQL Server y 12
vistas indexadas (una para cada mes). Así internamente tendríais una sola
tabla, y las consultas las podríais hacer sobre las vistas indexadas.

¿ Que volumen de datos tendrían esas tablas ?

Un saludo
Salvador Ramos
Murcia - España
[Microsoft MVP SQL Server]
www.helpdna.net
¿Te interesa participar en las reuniones
del grupo de Usuarios de SQL-Server y .NET
Se harán en levante de España, (Alicante o Murcia)?

"Quique" escribió en el mensaje
news:

Hola a todos,

tenemos una aplicación que, por el volumen de información que maneja, nos
obliga a crear particiones por meses en 5 tablas del modelo. De esta
forma, mantendremos un histórico de 12 meses que iremos rotando. La idea
no es particionar para poder ejecutar las consultas en paralelo, sino por
facilitar el borrado y mantenimiento.

Cuando empezamos a analizar cómo crear estas particiones en SQL SERVER (la
aplicación también corre con Oracle y ahí hemos podido implementarlas sin
problemas), empezó nuestro "calvario".

Investigando, descubrimos que debíamos crear 12 tablas por cada una de las
que deseamos particionar y, en cada una de las 12, añadir una CHECK que
indique qué mes es el que contiene. A continuación, se crea una vista cuya
definición es un UNION ALL de cada una de las 12 tablas. Hasta aquí bien.

El problema es que una de las 5 tablas que deseamos particionar no tiene
clave primaria. Las otras cuatro sí la tienen y, además, el campo por el
que particionamos pertenece a ella.

La tabla no tiene clave primaria, porque intervienen 22 campos y no es
relevante, al controlar nosotros las inserciones. Tan sólo creamos dos
índices no únicos para optimizar las consultas que se realizan sobre ella.

Al ir a crear una partición, en SQL Server te exige que el campo sobre el
que indicas la condición forme parte de la clave primaria. Por tanto, como
no es viable crear la clave primaria con 22 campos (aparte de que el
límite son 15, el índice ocupa más que la tabla) y no queremos crear un
campo que guarde el valor de la concatenación de todos, nos planteamos
crear una PK con la fecha y un secuencial (IDENTITY). Pero nos encontramos
que en tablas particionadas no se permite usar esta funcionalidad.

Decidimos abordar el problema con un trigger que informara este valor
secuencial y nos permitiera simular la PK, pero el problema es que las
inserciones se hacen mediante INSERT...SELECT (con más de un registro) y
no éramos capaces de que le asignara un número diferente a cada registro,
sino el mismo a cada uno de los obtenidos en el SELECT.

¿Nos puede indicar alguien si hay alguna forma más sencilla de gestionar
las particiones o, si hasta ahora no hemos hecho nada mal, cómo podemos
crear una clave primaria "en tiempo de ejecución" con un INSERT..SELECT?
Por ejemplo, algo similar a la función ROWNUM de Oracle concatenada con un
timestamp. ¿Hay algo equivalente en SQL SERVER?

Contar con el agravante de que tenemos una aplicación ya rodada y con dos
gestores y queremos tratar de tener que montar un lío tremendo sólo por
SQL Server.

Muchas gracias por anticipado.

Un saludo

Respuesta Responder a este mensaje
#2 e.lorenzo
15/12/2004 - 16:59 | Informe spam
Depende de los clientes, en algunas podemos superar los 25 millones de
registros en un mes (más de 6 Gb). La cuestión es que queremos las
particiones en tablas para que, cuando llegue el mes 13, borre el 1 y cree
una nueva tabla para el 13. Si no, con los DELETE y reconstrucción de
índices se queda frita la máquina.

Salvador Ramos wrote:

Otra altenativa sería tener una sola tabla en la versión de SQL Server y 12
vistas indexadas (una para cada mes). Así internamente tendríais una sola
tabla, y las consultas las podríais hacer sobre las vistas indexadas.

¿ Que volumen de datos tendrían esas tablas ?
Respuesta Responder a este mensaje
#3 Maxi
15/12/2004 - 17:26 | Informe spam
Hola, perdon q me meta no ;) pero la idea de Salvador me parece buena :)
quizas lo que debas hacer para que el delete no se vea afectado tanto, es
hacerlo en parcelas (paginar) con lo cual podrias hacer un SP que pagine de
a X registros para eliminar el historial.

Ojo es solo una opcion mas


Salu2
Maxi


"Quique" escribió en el mensaje
news:

Depende de los clientes, en algunas podemos superar los 25 millones de
registros en un mes (más de 6 Gb). La cuestión es que queremos las
particiones en tablas para que, cuando llegue el mes 13, borre el 1 y cree
una nueva tabla para el 13. Si no, con los DELETE y reconstrucción de
índices se queda frita la máquina.

Salvador Ramos wrote:

Otra altenativa sería tener una sola tabla en la versión de SQL Server y
12
vistas indexadas (una para cada mes). Así internamente tendríais una sola
tabla, y las consultas las podríais hacer sobre las vistas indexadas.



¿ Que volumen de datos tendrían esas tablas ?





Respuesta Responder a este mensaje
#4 Javier Loria
15/12/2004 - 18:08 | Informe spam
Hola:
A bueno, con ese volumen no deberias tener problemas. Cuando hablaste de
muchas filas pense en 30-50 millones diarias.
Con un servidor robusto no deberias tener ningun problema.
Saludos,


Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda

"Quique" wrote in message
news:

Depende de los clientes, en algunas podemos superar los 25 millones de
registros en un mes (más de 6 Gb). La cuestión es que queremos las
particiones en tablas para que, cuando llegue el mes 13, borre el 1 y cree
una nueva tabla para el 13. Si no, con los DELETE y reconstrucción de
índices se queda frita la máquina.

Salvador Ramos wrote:

> Otra altenativa sería tener una sola tabla en la versión de SQL Server y


12
> vistas indexadas (una para cada mes). Así internamente tendríais una


sola
> tabla, y las consultas las podríais hacer sobre las vistas indexadas.

> ¿ Que volumen de datos tendrían esas tablas ?



Respuesta Responder a este mensaje
#5 e.lorenzo
15/12/2004 - 18:08 | Informe spam
No hay nada que perdonarte, al contrario.

Entiendo que los delete los realizaría por tramos y no me tostaría la
máquina, pero aún así, tendré que recomponer la tabla y los índices, pues
quedarían muy "perjudicados".

La cuestión es que tenemos un problema añadido. Las consultas de SQL
(tanto las de inserción como las de lectura) se construyen con un motor de
SQL que hemos desarrollado y éste incorpora el nombre de la tabla,
llamémosla X. En caso de que hiciera las particiones, la vista es la que
se denominaría X.

Por tanto, no podría crearme 12 vistas y seleccionar en tiempo de
ejecución a cuál debo consultar. Tengo una SQL "fija" a la que le añado el
filtro de mes.

No sé si me explico bien y alcanzáis a ver el problema.

Gracias de todas formas.

Un saludo
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida