2008-09-17 10 views
5

Dado el problema de que un procedimiento almacenado en SQL Server 2005, que se desplaza por un cursor, debe ejecutarse una vez por hora y tarda unos 5 minutos en ejecutarse, pero requiere una gran cantidad de tiempo del procesador:Comando WAITFOR

editar: Quitaría el cursor si pudiera, desafortunadamente, tengo que hacer un montón de procesamiento y ejecutar otros procesos/consultas almacenados basados ​​en la fila.

¿Puedo usar WAITFOR DELAY '0: 0: 0.1' antes de cada búsqueda para actuar como la versión de SQL de .Net's Thread.Sleep? De este modo, permite que los otros procesos se completen más rápido a expensas del tiempo de ejecución de este procedimiento.

¿O hay otra solución que no estoy viendo?

Gracias

Respuesta

4

Poner el WAITFOR dentro del bucle sería de hecho reducir la velocidad y permitir que otras cosas para ir más rápido. También podría considerar un bucle WHILE en lugar de un cursor, según mi experiencia, se ejecuta más rápido. También podría considerar mover el cursor a un cursor de avance rápido, de solo lectura, que puede limitar la cantidad de memoria que ocupa.

declare @minid int, @maxid int, @somevalue int 
select @minid = 1, @maxid = 5 
while @minid <= @maxid 
begin 
    set @somevalue = null 
    select @somevalue = somefield from sometable where id = @minid 
    print @somevalue 
    set @minid = @minid + 1 
    waitfor delay '00:00:00.1' 
end 
1

No estoy seguro si eso resolvería el problema. En mi humilde opinión, el problema de rendimiento con los cursores está alrededor de la cantidad de memoria que utilizas para mantener el conjunto de datos residente y recorrerlo, si luego agregas un waitfor dentro del bucle, estás acaparando recursos durante más tiempo.

Pero puedo estar equivocado aquí, lo que sugeriría es utilizar perfmon para comprobar el rendimiento del servidor en ambas condiciones, y luego tomar una decisión si vale la pena o no agregar la espera.

Mirando la etiqueta, asumo que estás usando MS SQL Server, y no cualquiera de los otros sabores.

0

Puede retrasar el procedimiento, pero eso podría ayudarlo o no. Depende de cómo funciona el procedimiento. Es en una transacción, por qué un cursor (terriblemente ineficiente en SQL Server), dónde está la ralentización, etc. Tal vez sería más conveniente volver a trabajar el procedimiento.

0

Supongo que cualquier código que tenga significa que los otros procesos no pueden acceder a la tabla de la que se deriva su cursor.

Siempre que haga que el cursor READONLY FASTWORD no bloquee las tablas de las que se deriva el cursor.

Sin embargo, si necesita escribir, WAITFOR no lo ayuda. Una vez que has bloqueado la mesa, está bloqueada.

Una opción sería hacer una instantánea de las tablas en una tabla temporal, y luego hacer un cursor/loop en su lugar. Entonces no estaría bloqueando las tablas subyacentes, pero igualmente las tablas podrían cambiar mientras procesa la instantánea ...

Dems