Nuestro flujo ETL tiene una instrucción SELECT INTO de larga duración, que crea una tabla sobre la marcha y la completa con varios cientos de millones de registros.
La declaración se parece a algo como SELECT ... INTO DestTable FROM SrcTable
Para fines de monitoreo, nos gustaría tener una idea aproximada del progreso de esta declaración, mientras se ejecuta (recuento de filas, número de bytes escritos o similar).
Intentamos lo siguiente en vano:
-- Is blocked by the SELECT INTO statement:
select count(*) from DestTable with (nolock)
-- Returns 0, 0:
select rows, rowmodctr
from sysindexes with (nolock)
where id = object_id('DestTable')
-- Returns 0:
select rows
from sys.partitions
where object_id = object_id('DestTable')
Además, podemos ver la transacción en sys.dm_tran_active_transactions, pero no pude encontrar una manera de obtener el recuento de filas afectadas en un determinado transaction_id(algo similar a @@ROWCOUNTquizás, pero con el transaction_idargumento como).
Entiendo que en SQL Server, la instrucción SELECT INTO es tanto una instrucción DDL como una DML en una, y como tal, la creación implícita de la tabla será una operación de bloqueo. Todavía creo que debe haber alguna forma inteligente de obtener algún tipo de información de progreso mientras se ejecuta la declaración.

Respuestas:
Sospecho que
rowsensys.partitions0 es debido a que aún no se ha comprometido. Pero esto no significa que SQL Server desconozca qué irá allí si la transacción se confirma. La clave está en recordar que todas las operaciones pasan primero por el Buffer Pool (es decir, la memoria), independientemente de COMMIT o ROLLBACK de la operación. Por lo tanto, podemos buscarsys.dm_os_buffer_descriptorsesa información:Si desea ver los detalles, descomente la primera fila de elementos en la
SELECTlista, comente las 3 líneas restantes.Probé ejecutando lo siguiente en una sesión y luego ejecutando repetidamente la consulta anterior en otra.
fuente
¿Uno fuera o en curso?
Si esta es una necesidad que se puede anticipar por adelantado *, puede usar
sys.dm_exec_query_profilesConexión 1 (sesión 55)
Conexión 2
Es posible que deba sumar los recuentos de filas devueltos si
SELECT INTOestá utilizando paralelismo .* La sesión que desea monitorear usando este DMV debe estar habilitada para la recopilación de estadísticas usando
SET STATISTICS PROFILE ONoSET STATISTICS XML ON. Solicitar un plan de ejecución "real" de SSMS también funciona (porque establece la última opción).fuente
No creo que haya una manera de obtener recuentos de filas, pero puede estimar la cantidad de datos escritos mirando:
Si tiene algún tipo de idea de cuántas páginas debería ocupar el montón cuando haya terminado, debería poder calcular el% completado. La última consulta no será rápida a medida que la tabla se agrande. Y probablemente sea más seguro ejecutar lo anterior debajo
READ UNCOMMITTED(y no es frecuente que lo recomiendo, para nada).fuente
Si pudieras cambiar el
INSERTde una un
entonces su
select count(*) from DestTable with (nolock)consulta funcionaría.Si esto no es posible, puede usar sp_WhoIsActive (o profundizar en los DMV) para controlar cuántas escrituras hace la consulta. Esta sería una medida bastante aproximada, pero podría ser útil si basas el número de escrituras que normalmente hace.
Debería poder obtener un registro mínimo con lo
INSERTanterior si agregaWITH (TABLOCK).fuente
INSERTanterior si agregaWITH(TABLOCK)BULK_OPERATIONbloquea.