Notre flux ETL a une instruction SELECT INTO de longue durée, qui crée une table à la volée et la remplit de plusieurs centaines de millions d'enregistrements.
La déclaration ressemble à quelque chose SELECT ... INTO DestTable FROM SrcTable
À des fins de surveillance, nous aimerions avoir une idée approximative de la progression de cette instruction pendant son exécution (approximativement nombre de lignes, nombre écrit d'octets ou similaire).
Nous avons essayé ce qui suit en vain:
-- 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')
De plus, nous pouvons voir la transaction dans sys.dm_tran_active_transactions
, mais je n'ai pas pu trouver un moyen d'obtenir le nombre de lignes affectées sur une donnée transaction_id
(quelque chose de similaire à @@ROWCOUNT
peut-être, mais avec l' transaction_id
argument as).
Je comprends que sur SQL Server, l'instruction SELECT INTO est à la fois une instruction DDL et une instruction DML, et en tant que telle, la création de table implicite sera une opération de verrouillage. Je pense toujours qu'il doit y avoir un moyen intelligent d'obtenir une sorte d'informations sur la progression pendant l'exécution de la déclaration.
Réponses:
Je pense que
rows
danssys.partitions
est 0 en raison de ne pas être encore engagé. Mais cela ne signifie pas que SQL Server ne sait pas ce qui se passera si la transaction est validée. La clé est de se rappeler que toutes les opérations passent d'abord par le pool de tampons (c'est-à-dire la mémoire), indépendamment de COMMIT ou ROLLBACK de l'opération. Par conséquent, nous pouvons recherchersys.dm_os_buffer_descriptors
ces informations:Si vous souhaitez voir les détails, décommentez la première ligne d'éléments de la
SELECT
liste, commentez les 3 lignes restantes.J'ai testé en exécutant ce qui suit dans une session, puis en exécutant à plusieurs reprises la requête ci-dessus dans une autre.
la source
Unique ou en cours?
Si c'est un besoin qui peut être anticipé à l'avance * vous pouvez utiliser
sys.dm_exec_query_profiles
Connexion 1 (session 55)
Connexion 2
Vous devrez peut-être additionner le nombre de lignes retournées si le parallélisme
SELECT INTO
est utilisé .* La session que vous souhaitez surveiller à l'aide de ce DMV doit être activée pour la collecte de statistiques à l'aide de
SET STATISTICS PROFILE ON
ouSET STATISTICS XML ON
. La demande d'un plan d'exécution "réel" à SSMS fonctionne également (car elle définit la dernière option).la source
Je ne pense pas qu'il existe un moyen d'obtenir le nombre de lignes, mais vous pouvez estimer la quantité de données écrites en regardant:
Si vous avez une idée du nombre de pages que le tas doit occuper une fois terminé, vous devriez pouvoir calculer% complet. Cette dernière requête ne sera pas rapide car la table s'agrandit. Et probablement le plus sûr pour exécuter ce qui précède
READ UNCOMMITTED
(et ce n'est pas souvent je le recommande, pour rien).la source
Si vous pouviez changer
INSERT
d'unà un
alors votre
select count(*) from DestTable with (nolock)
requête fonctionnerait.Si cela n'est pas possible, vous pouvez utiliser sp_WhoIsActive (ou plonger dans les DMV) pour surveiller le nombre d'écritures de la requête. Ce serait une jauge plutôt approximative mais pourrait être utile si vous basez le nombre d'écritures qu'il fait normalement.
Vous devriez pouvoir obtenir une journalisation minimale avec ce qui
INSERT
précède si vous ajoutezWITH (TABLOCK)
.la source
INSERT
précède si vous ajoutezWITH(TABLOCK)
BULK_OPERATION
verrou.