Pregunta

Aquí está mi escenario:

Tengo un procedimiento almacenado simple que elimina un conjunto específico de filas de una tabla (diremos unas 30k filas) y luego inserta aproximadamente la misma cantidad de filas. Esto generalmente solo debería tomar unos segundos; sin embargo, la tabla tiene un activador que busca inserciones / eliminaciones e intenta imitar lo que sucedió con una tabla vinculada en otro servidor.

Este proceso a su vez es insoportablemente lento debido al disparador, y la tabla también se bloquea durante este proceso. Así que aquí están mis dos preguntas:

  1. Supongo que una parte decente de la desaceleración se debe al registro de transacciones. ¿Hay alguna manera de especificar en mi procedimiento almacenado que no deseo que se registre lo que está en el procedimiento?
  2. ¿Hay alguna manera de hacer mis comandos 'BORRAR DE' e 'INSERTAR EN' sin que bloquee la tabla durante todo el proceso?

¡Gracias!

edit - Gracias por las respuestas; Pensé que era el caso (no poder hacer ninguna de las anteriores), pero quería asegurarme. El gatillo se creó hace mucho tiempo y no parece muy eficiente, por lo que parece que mi próximo paso será ir a eso y descubrir qué se necesita y cómo se puede mejorar. Gracias!

¿Fue útil?

Solución

1) no, tampoco está realizando una operación mínimamente registrada como TRUNCATE o BULK INSERT

2) No, ¿cómo evitarías la corrupción?

Otros consejos

No asumiría automáticamente que el problema de rendimiento se debe al registro. De hecho, es probable que el desencadenador esté escrito de tal manera que esté causando problemas de rendimiento. Te animo a que modifiques tu pregunta original y muestres el código del activador.

No puede desactivar la integridad transaccional al modificar los datos. Puede ignorar los bloqueos cuando selecciona datos usando select * de la tabla (nolock) ; sin embargo, debe tener mucho cuidado y asegurarse de que su aplicación pueda realizar lecturas sucias.

No ayuda con su disparador, pero la solución al problema de bloqueo es realizar las transacciones en lotes más pequeños.

En lugar de

DELETE FROM Table WHERE <Condition>

Haz algo como

WHILE EXISTS ( SELECT * FROM table WHERE <condition to delete>)
BEGIN
  SET ROWCOUNT 1000
  DELETE FROM Table WHERE <Condition>
  SET ROWCOUNT 0
END

Puede deshabilitar temporalmente el activador, ejecutar su proceso y luego hacer lo que el activador estaba haciendo de manera más eficiente.

-- disable trigger
ALTER TABLE [Table] DISABLE TRIGGER [Trigger]
GO

-- execute your proc
EXEC spProc
GO

-- do more stuff to clean up / sync with other server
GO

-- enable trigger
ALTER TABLE [Table] ENABLE TRIGGER [Trigger]
GO
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top