Nosso fluxo ETL tem uma instrução SELECT INTO de longa duração, que cria uma tabela em tempo real e a preenche com várias centenas de milhões de registros.
A declaração é algo comoSELECT ... INTO DestTable FROM SrcTable
Para fins de monitoramento, gostaríamos de ter uma ideia aproximada do andamento desta instrução, enquanto ela está sendo executada (aprox. rowcount, número de bytes gravados ou similar).
Tentamos o seguinte sem sucesso:
-- 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')
Além disso, podemos ver a transação em sys.dm_tran_active_transactions
, mas não consegui encontrar uma maneira de obter a contagem de linhas afetadas em um determinado transaction_id
(algo semelhante a @@ROWCOUNT
talvez, mas com o transaction_id
argumento as).
Entendo que no SQL Server a instrução SELECT INTO é uma instrução DDL e DML em uma e, como tal, a criação implícita da tabela será uma operação de bloqueio. Ainda acho que deve haver alguma maneira inteligente de obter algum tipo de informação de progresso enquanto a instrução está em execução.
Eu suspeito que
rows
insys.partitions
é 0 devido a não ter sido confirmado ainda. Mas isso não significa que o SQL Server não saiba o que acontecerá se a transação for confirmada. A chave está em lembrar que todas as operações passam primeiro pelo Buffer Pool (ou seja, memória), independentemente de COMMIT ou ROLLBACK da operação. Portanto, podemos procurarsys.dm_os_buffer_descriptors
essas informações:Se você quiser ver os detalhes, remova o comentário da primeira linha de itens da
SELECT
lista e comente as 3 linhas restantes.Testei executando o seguinte em uma sessão e, em seguida, executando repetidamente a consulta acima em outra.
Um fora ou em curso?
Se esta for uma necessidade que pode ser antecipada* você pode usar
sys.dm_exec_query_profiles
Conexão 1 (sessão 55)
Conexão 2
Você pode precisar somar as contagens de linhas retornadas se
SELECT INTO
estiver usando paralelismo .* A sessão que você deseja monitorar usando este DMV deve ser habilitada para coleta de estatísticas usando
SET STATISTICS PROFILE ON
ouSET STATISTICS XML ON
. Solicitar um plano de execução "real" do SSMS também funciona (porque define a última opção).Não acho que haja uma maneira de obter contagens de linhas, mas você pode estimar a quantidade de dados gravados observando:
Se você tiver alguma ideia de quantas páginas o heap deve ocupar quando terminar, poderá calcular a % concluída. A última consulta não será rápida conforme a tabela fica maior. E provavelmente é mais seguro executar o procedimento acima
READ UNCOMMITTED
(e não é sempre que eu recomendo isso, para qualquer coisa).Se você pudesse mudar o
INSERT
de umpara um
então sua
select count(*) from DestTable with (nolock)
consulta funcionaria.Se isso não for possível, você pode usar sp_WhoIsActive (ou mergulhar nos DMVs) para monitorar quantas gravações a consulta faz. Isso seria um medidor bastante aproximado, mas poderia ser útil se você baseasse o número de gravações que normalmente faz.
Você deve conseguir obter um registro mínimo com o
INSERT
acima, se adicionarWITH (TABLOCK)
.