Grimpi IT Blog

marzo 19, 2011

Monitorear el progreso de una operación masiva de INSERT/DELETE sobre una tabla

Filed under: SQL Server, T-SQL — grimpi @ 11:47 pm

Supongamos que queremos monitorear el progreso de una operación intensiva de insert/delete sobre una tabla dentro de una transacción.
La primera opción que uno piensa es hacer un SELECT COUNT(*) FROM Tabla a medida que se ejecuta la operación de insertado
o borrado de datos. Lamentablemente salvo que tengamos un isolation level muy bajo, esta consulta va a quedar bloqueada
hasta que se termine la ejecución de la otra transacción, por lo tanto, no vamos a poder monitorear el progreso de la misma.

Veamos este ejemplo:

INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

Yo quiero copiar el contenido de la tabla MaestroClientes de un servidor externo a mi base de datos. Supongamos que la tabla MaestroClientes contiene 20 millones de registros, lo que significa que aun en optimas condiciones, el proceso seguramente duraría al menos un par de minutos.
Ahora mientras se ejecuta el INSERT de mas arriba, hagamos un SELECT COUNT(*) FROM TablaCliente en otra sesión. Como verán, la consulta queda en espera, hasta que se termine la transacción que realiza el insertado de datos.
Sin embargo, si consultamos la vista de sistema sys.partitions, vamos a encontrar información muy interesante, especialmente en el campo Rows. Consultando esta vista para la tabla que deseamos monitorear a medida que se ejecuta la transacción, vamos a ver que el campo rows de esa vista varia.

Ejemplo:

SELECT object_id, rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

A diferencia del SELECT COUNT(*) que hacíamos antes, esta consulta no queda bloqueada, pudiendo ser ejecutada varias veces mientras se realiza la transacción de insertado.
Entonces, como hacemos para ver el porcentaje de progreso?

1) Capturamos el total de registros que vamos a insertar:
SELECT COUNT(*) FROM ServidorLinkeado.dbo.MaestroClientes.

2) Capturamos el total de registros que ya existe en la tabla de destino:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

3) Ejecutamos la transacción que realiza el insertado masivo de datos:
INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

4) Mientras se ejecuta la transacción, abrimos una nueva conexión y ejecutamos reiteradamente esta consulta:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

 

 

Exactamente aplica la misma lógica, en el caso de que nos interese monitorear una operación de DELETE. La única diferencia es que en la columna rows de la tabla sys.partitions, veremos que su número desciende sucesivamente.

1 comentario »

  1. Las consultas en la vista sys.partitions deberian ser algo asi ?

    select rows from sys.partitions where OBJECT_ID =OBJECT_ID(N’nombretabla’)
    — o
    select rows from sys.partitions where OBJECT_name(OBJECT_ID )=’nombretabla’

    Comentario por Damian — septiembre 12, 2012 @ 10:48 pm


RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Crea un blog o un sitio web gratuitos con WordPress.com.

A %d blogueros les gusta esto: