Carga masiva: he de desactivar indices?

20/05/2004 - 10:39 por anna_marcos | Informe spam
Hola a todos.

Tengo un proceso en sqlserver 2k SP3.
El proceso que lanzo ha de tratar millones de registros cada día.
De todo el proceso, hay un punto donde quito indices, cargo unos
50.000 registros (inserts y updates), y luego vuelvo a poner los
índices.
Pensaba que este sistema aceleraría la carga de registros, al no haber
índices por en medio.
La cuestión es que es así, pero el problema que tengo ahora es que
solo en quitar y volver a poner los índices tarda muchísimo !!!!!
Mucho más que la carga de los 50.000 registros !!!!!
La tabla tiene 8 millones de registros.

Supongo que estoy haciéndolo mal, y no debería tocar los índices.
Además, existen otros procesos que se ejecutan en paralelo con este
proceso a diferentes tablas. Entre ellas no tienen nada que ver, pero
corren bajo el mismo servidor. Quizás eso también esté
penalizando.

Además, llega un momento en que pierde el usuario de conexión a la
bbdd cuando lleva la mitad del índice creado (unos 20 minutos de
proceso), y para el proceso. (El error dice user: NULL).

Sin embargo, ese mismo proceso lo ejecuto en otro punto, y no peta ni
pierde el usuario de conexión.
No siempre pierde el usuario de conexión, pero sí muy a menudo.


Me imagino que tendía que:
1) no tocar los índices
2) no ejecutar en paralelo esos procesos.

No sé qué hacer, mi idea lógicamente es que no pierda el usuario de
conexión, y que se agilice el tiempo de carga de datos.

Por cierto, el mecanismo de mis procesos nacen desde un programa VB
que mediante un SHELL va lanzando otros programas VB. Estos últimos
son los que se conectan con la BBDD y ejecutan los stored procedures.

Gracias de antemano a todos por la atención.

Preguntas similare

Leer las respuestas

#1 Carlos Sacristan
20/05/2004 - 11:44 | Informe spam
Bueno, más que quitar los índices (puede ser interesante tenerlos para
las búsquedas de los registros a actualizar, por ejemplo), lo que puede
penalizar el rendimiento pueden ser las validaciones que tiene que realizar
el motor para garantizar la integridad de los datos (checks, claves
foráneas, etc). Ten en cuenta que en tablas grandes (bueno, lo habrás podido
comprobar), la recreación de un índice es una operación bastante costosa.

También miraría qué es lo que hace ese procedimiento para que sea más
eficiente (evitar cursores es lo primero que se debería intentar hacer,
mirar posibles bloqueos que se puedan producir)

Si son cargas de datos, lo haría mediante algún programa de carga masiva
(bcp, sin ir más lejos. Echa un vistazo en los BOL si no lo conoces)

En principio creo que puedes ir mirando eso, ya nos contarás...

Un saludo

-
"Sólo sé que no sé nada. " (Sócrates)

Por favor, responder únicamente al foro
Se agradece la inclusión de sentencias DDL


"anna" escribió en el mensaje
news:
Hola a todos.

Tengo un proceso en sqlserver 2k SP3.
El proceso que lanzo ha de tratar millones de registros cada día.
De todo el proceso, hay un punto donde quito indices, cargo unos
50.000 registros (inserts y updates), y luego vuelvo a poner los
índices.
Pensaba que este sistema aceleraría la carga de registros, al no haber
índices por en medio.
La cuestión es que es así, pero el problema que tengo ahora es que
solo en quitar y volver a poner los índices tarda muchísimo !!!!!
Mucho más que la carga de los 50.000 registros !!!!!
La tabla tiene 8 millones de registros.

Supongo que estoy haciéndolo mal, y no debería tocar los índices.
Además, existen otros procesos que se ejecutan en paralelo con este
proceso a diferentes tablas. Entre ellas no tienen nada que ver, pero
corren bajo el mismo servidor. Quizás eso también esté
penalizando.

Además, llega un momento en que pierde el usuario de conexión a la
bbdd cuando lleva la mitad del índice creado (unos 20 minutos de
proceso), y para el proceso. (El error dice user: NULL).

Sin embargo, ese mismo proceso lo ejecuto en otro punto, y no peta ni
pierde el usuario de conexión.
No siempre pierde el usuario de conexión, pero sí muy a menudo.


Me imagino que tendía que:
1) no tocar los índices
2) no ejecutar en paralelo esos procesos.

No sé qué hacer, mi idea lógicamente es que no pierda el usuario de
conexión, y que se agilice el tiempo de carga de datos.

Por cierto, el mecanismo de mis procesos nacen desde un programa VB
que mediante un SHELL va lanzando otros programas VB. Estos últimos
son los que se conectan con la BBDD y ejecutan los stored procedures.

Gracias de antemano a todos por la atención.
Respuesta Responder a este mensaje
#2 Javier Loria
20/05/2004 - 16:25 | Informe spam
Hola Anna:
Yo creo que vas por buen camino. Lo unico es que si los datos vienen de
un archivo externo es mas rapido hacer lo siguiente:
a) Cargar los datos a una Base de Datos Intermedia, en esta BD, la Tabla
no tiene indices, ni llave primaria, ni constraints. Esta base de datos
tiene marcada la opcion de recuperacion 'BULK LOGGED'.
b) Revisar que no se rompan la integridad en los Datos a importar
haciendo SELECT's para probar que los datos son integros, por ejemplo que no
se repite la llave primaria, que no se rompen las relaciones, que se cumplen
los CHECKS, etc.
c) Luego que estan limpios los datos lo copias de un lado a la Tabla de
Produccion, en este caso previamente puedes deshabilitar previamente los
CHECKS y las Llaves Foraneas, para luego habilitarlas con el NOCHECK.
Esto es dificil de construir pero suele ser la opcion mas rapida.
Por ultimo aun cuando no venga de un archivo externo puedes revisar la
forma en que estan construidos los indices clustered de las tablas,
sobretodo si los datos que se importan son sequenciales (llaves
artificiales, numeros consecutivos, basados en fechas, etc.) porque puede
ser estes insertando todo al final y produciendo muchos splits en el indice
pricipalmente el Clustered. Entonces vale la pena usar las opciones
FILLFACTOR y PADINDEX, en este tipo de tablas un FILLFACTOR alto y un
PADINDEX bajo suelen ser la mejor opcion para accelerar la carga sin
penalizar demasiado las consultas.
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.

anna escribio:
Hola a todos.

Tengo un proceso en sqlserver 2k SP3.
El proceso que lanzo ha de tratar millones de registros cada día.
De todo el proceso, hay un punto donde quito indices, cargo unos
50.000 registros (inserts y updates), y luego vuelvo a poner los
índices.
Pensaba que este sistema aceleraría la carga de registros, al no haber
índices por en medio.
La cuestión es que es así, pero el problema que tengo ahora es que
solo en quitar y volver a poner los índices tarda muchísimo !!!!!
Mucho más que la carga de los 50.000 registros !!!!!
La tabla tiene 8 millones de registros.

Supongo que estoy haciéndolo mal, y no debería tocar los índices.
Además, existen otros procesos que se ejecutan en paralelo con este
proceso a diferentes tablas. Entre ellas no tienen nada que ver, pero
corren bajo el mismo servidor. Quizás eso también esté
penalizando.

Además, llega un momento en que pierde el usuario de conexión a la
bbdd cuando lleva la mitad del índice creado (unos 20 minutos de
proceso), y para el proceso. (El error dice user: NULL).

Sin embargo, ese mismo proceso lo ejecuto en otro punto, y no peta ni
pierde el usuario de conexión.
No siempre pierde el usuario de conexión, pero sí muy a menudo.


Me imagino que tendía que:
1) no tocar los índices
2) no ejecutar en paralelo esos procesos.

No sé qué hacer, mi idea lógicamente es que no pierda el usuario de
conexión, y que se agilice el tiempo de carga de datos.

Por cierto, el mecanismo de mis procesos nacen desde un programa VB
que mediante un SHELL va lanzando otros programas VB. Estos últimos
son los que se conectan con la BBDD y ejecutan los stored procedures.

Gracias de antemano a todos por la atención.
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida