Наш поток ETL имеет длительный оператор SELECT INTO, который создает таблицу на лету и наполняет ее несколькими сотнями миллионов записей.
Заявление выглядит примерно так SELECT ... INTO DestTable FROM SrcTable
В целях мониторинга мы хотели бы получить приблизительное представление о ходе выполнения этого оператора во время его выполнения (приблизительное количество строк, записанное число байтов или подобное).
Мы попробовали следующее безрезультатно:
-- 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')
Кроме того, мы можем видеть транзакцию sys.dm_tran_active_transactions
, но я не смог найти способ получить количество затронутых строк в заданном transaction_id
(что-то похожее на @@ROWCOUNT
возможно, но с transaction_id
аргументом as).
Я понимаю, что на SQL Server оператор SELECT INTO является одновременно оператором DDL и DML, и поэтому создание неявных таблиц будет операцией блокировки. Я все еще думаю, что должен быть какой-то умный способ получить какую-то информацию о прогрессе во время выполнения оператора.
Ответы:
Я подозреваю, что
rows
вsys.partitions
это 0 из-за еще не совершено. Но это не означает, что SQL Server не знает, что произойдет, если транзакция будет зафиксирована. Главное - помнить, что все операции сначала проходят через буферный пул (т. Е. Память), независимо от COMMIT или ROLLBACK операции. Следовательно, мы можем искатьsys.dm_os_buffer_descriptors
эту информацию:Если вы хотите увидеть детали, раскомментируйте первый ряд элементов в
SELECT
списке, закомментируйте оставшиеся 3 строки.Я проверил, запустив следующее в одном сеансе, а затем повторно запустил запрос выше в другом.
источник
Один выходной или продолжающийся?
Если это необходимо, что можно ожидать заранее * вы можете использовать
sys.dm_exec_query_profiles
Соединение 1 (сеанс 55)
Соединение 2
Вы , возможно , потребуется просуммировать строк счетчики возвращаемые если
SELECT INTO
есть используя параллелизм .* Сеанс, который вы хотите отслеживать с помощью этого DMV, должен быть включен для сбора статистики с помощью
SET STATISTICS PROFILE ON
илиSET STATISTICS XML ON
. Запрос «фактического» плана выполнения из SSMS также работает (потому что он устанавливает последний вариант).источник
Я не думаю, что есть способ получить количество строк, но вы можете оценить количество записанных данных, посмотрев на:
Если у вас есть какое-то представление о том, сколько страниц должна занять куча, когда вы закончите, вы сможете уточнить% выполнения. Последний запрос не будет быстрым, поскольку таблица становится больше. И, вероятно, безопаснее всего запустить выше
READ UNCOMMITTED
(и это не часто, я рекомендую это, для чего-либо).источник
Если бы вы могли изменить
INSERT
отк
тогда ваш
select count(*) from DestTable with (nolock)
запрос будет работать.Если это невозможно, вы можете использовать sp_WhoIsActive (или углубиться в DMV), чтобы отслеживать, сколько записей выполняет запрос. Это было бы довольно грубым показателем, но могло бы быть полезным, если бы вы указали количество записей, которые оно обычно выполняет.
Вы должны быть в состоянии получить минимальное логирование с
INSERT
вышеупомянутым, если вы добавитеWITH (TABLOCK)
.источник
INSERT
если вы добавитеWITH(TABLOCK)
BULK_OPERATION
блокировку.