Nosso fluxo de ETL possui uma instrução SELECT INTO de longa duração, que cria uma tabela rapidamente e a preenche com várias centenas de milhões de registros.
A declaração parece algo como SELECT ... INTO DestTable FROM SrcTable
Para fins de monitoramento, gostaríamos de ter uma idéia aproximada do progresso dessa instrução enquanto ela está sendo executada (aproximadamente número de linhas, número de bytes gravados ou semelhante).
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 sys.dm_tran_active_transactions
, mas não consegui encontrar uma maneira de obter a contagem de linhas afetadas em um dado 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 uma maneira inteligente de obter algum tipo de informação sobre o progresso enquanto a instrução está sendo executada.
Respostas:
Eu suspeito que
rows
insys.partitions
é 0 devido a não ter sido confirmado ainda. Mas isso não significa que o SQL Server desconheça o que ocorrerá se a transação for confirmada. A chave é lembrar que todas as operações passam pelo Buffer Pool (ou seja, memória) primeiro, 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 executando repetidamente a consulta acima em outra.
fonte
Um fora ou em curso?
Se for necessário antecipar *, você pode usar
sys.dm_exec_query_profiles
Conexão 1 (sessão 55)
Conexão 2
Pode ser necessário somar as contagens de linhas retornadas se
SELECT INTO
estiver usando paralelismo .* A sessão que você deseja monitorar usando esta DMV deve estar ativada para coleta de estatísticas usando
SET STATISTICS PROFILE ON
ouSET STATISTICS XML ON
. A solicitação de um plano de execução "real" do SSMS também funciona (porque define a última opção).fonte
Não acho que haja uma maneira de obter contagens de linhas, mas você pode estimar a quantidade de dados gravados observando:
Se você tem algum tipo de idéia de quantas páginas o heap deve ocupar ao terminar, você deve conseguir% de conclusão. A última consulta não será rápida à medida que a tabela aumentar. E provavelmente o mais seguro é executar o descrito acima
READ UNCOMMITTED
(e geralmente não é recomendável, para qualquer coisa).fonte
Se você pudesse mudar o
INSERT
depara um
sua
select count(*) from DestTable with (nolock)
consulta funcionaria.Se isso não for possível, você poderá usar sp_WhoIsActive (ou mergulhar nas DMVs) para monitorar quantas gravações a consulta faz. Esse seria um indicador bastante aproximado, mas poderia ser útil se você basear o número de gravações que normalmente realiza.
Você poderá obter um log mínimo com o
INSERT
descrito acima, se adicionarWITH (TABLOCK)
.fonte
INSERT
itens acima, se adicionar #WITH(TABLOCK)
BULK_OPERATION
bloqueio.