¿A qué se debe este mensaje de error?

09/02/2004 - 16:23 por Eje | Informe spam
Algunas veces en un procedimiento almacenado recibo este mensaje de error:

Servidor: mensaje 845, nivel 17, estado 1, línea 1
Se excedió el tiempo de espera del tipo de pestillo del búfer 2 para la
página (1:1610435), Id. de base de datos 5.

El procedimiento aún así termina sin errores, puesto que al final de él
tengo un mensaje de información y este aparece tras el mensaje de error, con
toda normalidad.
El procedimiento llena un cursor con unos datos y por cada fila del cursor
realiza una serie de cálculos haciendo consultas en varias tablas y grabando
el resultado de cada cálculo en una tabla temporal que después vuelca en una
tabla real de la BD. Dado que tengo mensajes de error antes de llenar el
cursor y antes de terminar, y que el mensaje de error sale entre ambos,
deduzco que el mensaje debe dar en el proceso de cada línea del cursor, al
grabar en la tabla temporal o al grabar la tabla temporal en la tabla real.
Ya digo que el error no sale siempre, además es un procedimiento que tarda
aprox. 8 horas y el error aparece cuando termina, con lo cual no puedo hacer
pruebas rápidas para ver por qué da y arreglaro.
A ver si alguien puede darme alguna pista de por qué ocurre esto.

Un saludo

Preguntas similare

Leer las respuestas

#6 Eje
10/02/2004 - 09:01 | Informe spam
Adrian D. Garcia

7 hs????
Por lo que realiza el proceso no deberia tardar mas de 20 minutos

1) El calculo de fechas se puede resolver con un SELECT simple?



No, es un cálculo de meses y años según la fecha y el tipo de cálculo que le
indiquen al procedimiento, pero esto es poco costoso y se resuelve con 3 o 4
de if anidados.

2) No se puede resolver con JOINS la consultas a las 15 tablas? Creo que


si

Pues viendo la respuesta de José Mariano me he dado cuenta de que es muy
posible que sí sea así, voy a probarlo ahora mismo y os cuento.
Incluso luego intentaré quitar directamente el cursor y obtener toda la
información con una select con subconsultas en su interior.
Os mantendré informados.

3) Si hay varios casos de calculos se podria generar una tabla temporal de
movimientos con el UNION y los JOINS de las demas tablas, luego si hay
varios casos de calculos diferentes se podria hacer varias instrucciones


de
UPDATE o INSERT diferentes en la tabla de resultado.



El UNION únicamente sirve para extraer qué registros tengo que calcular. El
cálculo actualmente es igual para todos los registros, pero sí es cierto que
si cambiara (antiguamente sí que había modificadores diferentes a los
cálculos) podría hacerse con UPDATE a la tabla temporal, me lo apunto ;)

4) El traspaso de informacion de la tabla temporal a la tabla real tambien
creo que se podria hacer con una instruccion de INSERT SELECT o UPDATE.



Sí, eso está hecho con INSERT SELECT

Un saludo
Respuesta Responder a este mensaje
#7 Adrian D. Garcia
10/02/2004 - 20:57 | Informe spam
Mantennos al tanto de los resultados que vas obteniendo, si?
Creo que nos va a servir a todos para futuras referencias. El usar cursores
en procesos batch son un tema recurrente en las listas.
Saludos
Adrian D. Garcia
MCSD
NDSoft Consultoria y Desarrollo

"Eje" wrote in message
news:c0a330$143tcu$
Adrian D. Garcia
>
> 7 hs????
> Por lo que realiza el proceso no deberia tardar mas de 20 minutos
>
> 1) El calculo de fechas se puede resolver con un SELECT simple?

No, es un cálculo de meses y años según la fecha y el tipo de cálculo que


le
indiquen al procedimiento, pero esto es poco costoso y se resuelve con 3 o


4
de if anidados.

> 2) No se puede resolver con JOINS la consultas a las 15 tablas? Creo que
si

Pues viendo la respuesta de José Mariano me he dado cuenta de que es muy
posible que sí sea así, voy a probarlo ahora mismo y os cuento.
Incluso luego intentaré quitar directamente el cursor y obtener toda la
información con una select con subconsultas en su interior.
Os mantendré informados.

> 3) Si hay varios casos de calculos se podria generar una tabla temporal


de
> movimientos con el UNION y los JOINS de las demas tablas, luego si hay
> varios casos de calculos diferentes se podria hacer varias instrucciones
de
> UPDATE o INSERT diferentes en la tabla de resultado.

El UNION únicamente sirve para extraer qué registros tengo que calcular.


El
cálculo actualmente es igual para todos los registros, pero sí es cierto


que
si cambiara (antiguamente sí que había modificadores diferentes a los
cálculos) podría hacerse con UPDATE a la tabla temporal, me lo apunto ;)

> 4) El traspaso de informacion de la tabla temporal a la tabla real


tambien
> creo que se podria hacer con una instruccion de INSERT SELECT o UPDATE.

Sí, eso está hecho con INSERT SELECT

Un saludo


Respuesta Responder a este mensaje
#8 Eje
12/02/2004 - 09:31 | Informe spam
Adrian D. Garcia
Mantennos al tanto de los resultados que vas obteniendo, si?
Creo que nos va a servir a todos para futuras referencias. El usar


cursores
en procesos batch son un tema recurrente en las listas.



Bueno, parece que no acaba de funcionar sin el cursor. He sustituido todo el
proceso del cursor con las sucesivas SELECT por registro y el INSERT en la
tabla temporal por un gran INSERT SELECT en el que se vincula (con JOINs)
todas las tablas necesarias para devolver los resultados directamente.
Ahora tras casi 9 horas de proceso (O_O) me da un error porque TEMPDB se
queda sin espacio. Incluso amplié su espacio disponible a una partición
vacía de la red pero ha llegado a crecer hasta 60 Gb, llenándola también
(O_O).
Esto me hace sospechar que evidentemente tiene que haber algo mal o que
pueda cambiarse para evitar ese efecto. Mi primera idea ha sido pasar el
optimizador de índices para ver si me sobraban o faltaban índices que
agilizaran la consulta, porque tanto tiempo me parece excesivo, pero no he
conseguido que me devuelva resultados. Me dice que la carga de trabajo no
contiene sucesos o consultas que puedan optimizar la BD actual, tanto
metiendo sólo la SELECT que va en el INSERT SELECT como poniendo todo el
código del procedimiento almacenado.
Planteo cómo queda el INSERT SELECT por si acaso hay algo que se me está
escapando, porque por más vueltas que le doy no encuentro nada que
aparentemente pueda estar causando el mal funcionamiento.
Tablas involucradas:

Tabla R 22.632.973 registros
Tabla S 865.021 registros
Tabla D 2.446.060 registros
Tabla P 2.138.078 registros
Tabla C 22.886.080 registros

Todas tienen un índice agrupado sobre un campo que contiene el año-mes al
que corresponden los datos, así como otros índices por los campos por los
que se suele acceder, vincular y agrupar la información (todas las tablas
tienen los mismos índices ya que su estructura es idéntica).
Las tablas R y S son las principales en la consulta, ya que son las que
indican qué registros hay que seleccionar (aunque también se obtienen un par
de cantidades calculadas).
De las otras 3 tablas (D, P y C) únicamente se obtienen dos cantidades de
cada una, con la particularidad de que ambas cantidades se obtienen por
diferencia con registros anteriores de las mismas tablas. Es decir, las
tablas obtienen los valores acumulados a una determinada fecha, pero hay que
obtener la diferencia obtenida en un periodo (por ejemplo, tenemos el valor
acumulado a enero de 2004, pero se necesita sacar lo obtenido en el último
año, para lo cual hay que restarle el valor acumulado a enero de 2003).
Debido a esto las tablas D, P y C aparecen 2 veces cada una en la consulta,
una vez para extraer el dato al final del periodo y otra para el valor al
inicio del periodo.
Indicar que la vinculación con cada tabla se hace a través del contenido de
5 campos.
Y ya no sé qué más contaros, si necesitáis más datos o no me he expresado
claramente no teneis más que decirlo, yo seguiré por aquí mientras tanto
investigando a ver si doy con algo incorrecto.

Un saludo
Respuesta Responder a este mensaje
#9 Miguel Egea
13/02/2004 - 10:20 | Informe spam
No se si podremos ayudarte con ese volumen y sin estar delante de esa
máquina. Puedes poner la estructura (resumida a lo que interesa) de las 5
tablas y el objetivo. (Sé que igual lo has puesto antes, pero llevo algún
tiempo desconectado del grupo por sobrecarga de trabajo y no lo veo).
¡Gracias!


Saludos

Miguel Egea
Microsoft SQL-SERVER MVP
Brigada Anti-Cursores
"Eje" escribió en el mensaje
news:c0fdiv$16eerf$
Adrian D. Garcia
> Mantennos al tanto de los resultados que vas obteniendo, si?
> Creo que nos va a servir a todos para futuras referencias. El usar
cursores
> en procesos batch son un tema recurrente en las listas.

Bueno, parece que no acaba de funcionar sin el cursor. He sustituido todo


el
proceso del cursor con las sucesivas SELECT por registro y el INSERT en la
tabla temporal por un gran INSERT SELECT en el que se vincula (con JOINs)
todas las tablas necesarias para devolver los resultados directamente.
Ahora tras casi 9 horas de proceso (O_O) me da un error porque TEMPDB se
queda sin espacio. Incluso amplié su espacio disponible a una partición
vacía de la red pero ha llegado a crecer hasta 60 Gb, llenándola también
(O_O).
Esto me hace sospechar que evidentemente tiene que haber algo mal o que
pueda cambiarse para evitar ese efecto. Mi primera idea ha sido pasar el
optimizador de índices para ver si me sobraban o faltaban índices que
agilizaran la consulta, porque tanto tiempo me parece excesivo, pero no he
conseguido que me devuelva resultados. Me dice que la carga de trabajo no
contiene sucesos o consultas que puedan optimizar la BD actual, tanto
metiendo sólo la SELECT que va en el INSERT SELECT como poniendo todo el
código del procedimiento almacenado.
Planteo cómo queda el INSERT SELECT por si acaso hay algo que se me está
escapando, porque por más vueltas que le doy no encuentro nada que
aparentemente pueda estar causando el mal funcionamiento.
Tablas involucradas:

Tabla R 22.632.973 registros
Tabla S 865.021 registros
Tabla D 2.446.060 registros
Tabla P 2.138.078 registros
Tabla C 22.886.080 registros

Todas tienen un índice agrupado sobre un campo que contiene el año-mes al
que corresponden los datos, así como otros índices por los campos por los
que se suele acceder, vincular y agrupar la información (todas las tablas
tienen los mismos índices ya que su estructura es idéntica).
Las tablas R y S son las principales en la consulta, ya que son las que
indican qué registros hay que seleccionar (aunque también se obtienen un


par
de cantidades calculadas).
De las otras 3 tablas (D, P y C) únicamente se obtienen dos cantidades de
cada una, con la particularidad de que ambas cantidades se obtienen por
diferencia con registros anteriores de las mismas tablas. Es decir, las
tablas obtienen los valores acumulados a una determinada fecha, pero hay


que
obtener la diferencia obtenida en un periodo (por ejemplo, tenemos el


valor
acumulado a enero de 2004, pero se necesita sacar lo obtenido en el último
año, para lo cual hay que restarle el valor acumulado a enero de 2003).
Debido a esto las tablas D, P y C aparecen 2 veces cada una en la


consulta,
una vez para extraer el dato al final del periodo y otra para el valor al
inicio del periodo.
Indicar que la vinculación con cada tabla se hace a través del contenido


de
5 campos.
Y ya no sé qué más contaros, si necesitáis más datos o no me he expresado
claramente no teneis más que decirlo, yo seguiré por aquí mientras tanto
investigando a ver si doy con algo incorrecto.

Un saludo


Respuesta Responder a este mensaje
#10 Eje
13/02/2004 - 11:06 | Informe spam
Miguel Egea
No se si podremos ayudarte con ese volumen y sin estar delante de esa
máquina. Puedes poner la estructura (resumida a lo que interesa) de las 5
tablas y el objetivo. (Sé que igual lo has puesto antes, pero llevo algún
tiempo desconectado del grupo por sobrecarga de trabajo y no lo veo).
¡Gracias!



Pues la estructura es similar en todas las tablas. Todas contienen
movimientos económicos, y están compuestas por:
- Clave única de 6 campos, uno de los cuales indica el mes/año del
movimiento, el resto indican a qué corresponde el movimiento económico
dentro de diversas clasificaciones internas.
- Varios campos con los datos económicos en sí. 2 en 3 de las tablas, en las
tablas principales algunos más, aunque no demasiados.
- Un par de campos con información extra que no afectan al cálculo (sólo
presentes en las tablas principales).

Tabla R 22.632.973 registros
Tabla S 865.021 registros
Tabla D 2.446.060 registros
Tabla P 2.138.078 registros
Tabla C 22.886.080 registros

Como dije las tablas R y S son las tablas principales, que indican qué
registros hay que procesar, en virtud del periodo a calcular (con un BETWEEN
entre rangos de mes/año). Los movimientos económicos de ese periodo se
obtienen por medio de un SUM normal. Entre ellas se relacionan por 5 de los
campos principales con un FULL OUTER JOIN, ya que podría haber movimientos
de un registro en la tabla R y no en la tabla S y viceversa.
Con las otras 3 tablas únicamente se relacionan por 3 de los campos clave,
pero estas tablas tienen la particularidad de que sus datos económicos son
acumulados, con lo cual para obtener la diferencia obtenida en el periodo
hay que extraer el total en la fecha final de cálculo y restarle el total en
la fecha inicial de cálculo, para lo cual hay que hacer un LEFT JOIN doble
con cada tabla, uno para obtener el total final y otro para el total
inicial. Además, como podría haber movimientos en la tabla S y no en la R, y
viceversa, estos LEFT JOIN llevan un COALESCE para que extraiga los datos de
los campos clave de la tabla que tuviera datos (sospecho que esto pueda
tener gran parte de culpa del tiempo, pero no se me ocurre otra manera de
hacerlo).
Pongo un breve resumen de cómo quedan las clausulas FROM y WHERE de la
instrucción:

FROM (R FULL OUTER JOIN S ON and_con_los_5_campos_clave)
LEFT JOIN D ON join_por_3_campos_clave_con_coalesce AND anno_mes finperiodo
LEFT JOIN D1 ON join_por_3_campos_clave_con_coalesce AND anno_mes inicioperiodo
LEFT JOIN C ON join_por_3_campos_clave_con_coalesce AND anno_mes finperiodo
LEFT JOIN C1 ON join_por_3_campos_clave_con_coalesce AND anno_mes inicioperiodo
LEFT JOIN P ON join_por_3_campos_clave_con_coalesce AND anno_mes finperiodo
LEFT JOIN P1 ON join_por_3_campos_clave_con_coalesce AND anno_mes inicioperiodo
WHERE R.anno_mes BETWEEN inicioperiodo AND finperiodo OR S.anno_mes BETWEEN
inicioperiodo AND finperiodo

La instrucción funciona bien en las pruebas que he realizado con porciones
pequeñas de los datos, con lo cual sintáctica y funcionalmente es correcta;
pero en cuanto lo intento con partes más extensas, el tiempo se incrementa
enormemente y al final se llena TEMPDB.
A ver si se os ocurre algo, actualmente estoy intentando separarlo en 4
tablas temporales (una que almacene la unión de las 2 tablas principales y
otras 3 que almacenen los cálculos sobre las otras 3 tablas) para luego
unirlas en el momento de grabarse a la tabla real de destino.

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