Eu acho que a consulta a seguir, pelo menos, chegará bem perto. Ele utiliza um DMV que foi introduzido no SQL Server 2014: sys.dm_exec_query_profiles (e obrigado a Martin Smith por me apresentar por meio deste DBA.StackExchange relacionado: Resposta da instrução SELECT INTO :-).
Observe:
!! Você precisará adicionar SET STATISTICS PROFILE ON;
ou SET STATISTICS XML ON;
no lote de consulta que está fazendo o CREATE INDEX
(e colocado antes da CREATE INDEX
instrução, se isso não fosse óbvio); caso contrário, nenhuma linha será exibida nesta DMV para esse SPID / session_id
!!
O IN
operador é usado para filtrar a Index Insert
linha que, se incluída, aumentará os TotalRows
valores, o que distorcerá os cálculos, pois essa linha nunca mostra nenhuma linha processada.
A contagem de linhas exibida aqui (ie TotalRows
) é o dobro da contagem de linhas da tabela devido à operação de duas etapas, cada uma operando em todas as linhas: a primeira é uma "Verificação de tabela" ou "Verificação de índice em cluster" e a segunda é o tipo". Você verá "Verificação de tabela" ao criar um índice clusterizado ou criar um índice não clusterizado em um heap. Você verá "Verificação de índice em cluster" ao criar um índice não em cluster em um índice em cluster.
Esta consulta parece não funcionar ao criar índices filtrados. Por alguma razão, os índices filtrados a) não possuem a etapa "Classificar" eb) o row_count
campo nunca aumenta de 0.
Não tenho certeza do que estava testando antes, mas agora meus testes indicam que os índices filtrados são capturados por esta consulta. Doce. Embora tenha apenas cuidado para que a contagem de linhas possa estar desativada (vou ver se consigo consertar isso algum dia).
Ao criar um índice clusterizado em um heap que já possui índices não clusterizados, os índices não clusterizados precisam ser reconstruídos (para trocar o RID - RowID - pela (s) chave (s) de índice clusterizado)) e cada reconstrução do índice não clusterizado ser uma operação separada e, portanto, não refletida nas estatísticas retornadas por esta consulta durante a criação do Índice de Cluster.
Esta consulta foi testada contra:
- Criando:
- Índices não agrupados em um heap
- um índice agrupado (não existem índices não agrupados)
- Índices não agrupados na tabela / índice agrupado
- um índice agrupado quando já não existem índices agrupados
- Índices não agrupados exclusivos na tabela / índice agrupado
- Reconstrução (tabela com índice clusterizado e um índice não clusterizado; testado no SQL Server 2014, 2016, 2017 e 2019) via:
ALTER TABLE [schema_name].[table_name] REBUILD;
(only Clustered Index shows up when using this method)
ALTER INDEX ALL ON [schema_name].[table_name] REBUILD;
ALTER INDEX [index_name] ON [schema_name].[table_name] REBUILD;
DECLARE @SPID INT = 51;
;WITH agg AS
(
SELECT SUM(qp.[row_count]) AS [RowsProcessed],
SUM(qp.[estimate_row_count]) AS [TotalRows],
MAX(qp.last_active_time) - MIN(qp.first_active_time) AS [ElapsedMS],
MAX(IIF(qp.[close_time] = 0 AND qp.[first_row_time] > 0,
[physical_operator_name],
N'<Transition>')) AS [CurrentStep]
FROM sys.dm_exec_query_profiles qp
WHERE qp.[physical_operator_name] IN (N'Table Scan', N'Clustered Index Scan',
N'Index Scan', N'Sort')
AND qp.[session_id] = @SPID
), comp AS
(
SELECT *,
([TotalRows] - [RowsProcessed]) AS [RowsLeft],
([ElapsedMS] / 1000.0) AS [ElapsedSeconds]
FROM agg
)
SELECT [CurrentStep],
[TotalRows],
[RowsProcessed],
[RowsLeft],
CONVERT(DECIMAL(5, 2),
(([RowsProcessed] * 1.0) / [TotalRows]) * 100) AS [PercentComplete],
[ElapsedSeconds],
(([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]) AS [EstimatedSecondsLeft],
DATEADD(SECOND,
(([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]),
GETDATE()) AS [EstimatedCompletionTime]
FROM comp;
Saída de amostra:
Rows Percent Elapsed Estimated Estimated
CurrentStep TotalRows Processed RowsLeft Complete Seconds SecondsLeft CompletionTime
----------- --------- --------- -------- -------- ------- ----------- --------------
Clustered 11248640 4786937 6461703 42.56 4.89400 6.606223 2016-05-23
Index Scan 14:32:40.547
physical_operator_name
set paraN'Index Scan'
, em vez deN'Table Scan'
ouN'Clustered Index Scan'
. Além disso, será muito lento, pois executará várias pesquisas de RID.ALTER INDEX ALL
como mesmo (parcialmente)ALTER TABLE .. REBUILD
. Por favor revise :-).