Alur ETL kami memiliki SELECT INTO-statement yang sudah berjalan lama, yang membuat tabel dengan cepat, dan mengisinya dengan beberapa ratus juta catatan.
Pernyataan itu terlihat seperti SELECT ... INTO DestTable FROM SrcTable
Untuk tujuan pemantauan, kami ingin mendapatkan gambaran kasar tentang kemajuan pernyataan ini, ketika sedang dieksekusi (kira-kira jumlah baris, jumlah byte tertulis, atau serupa).
Kami mencoba yang berikut ini tanpa hasil:
-- 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')
Lebih jauh, kita bisa melihat transaksi dalam sys.dm_tran_active_transactions
, tetapi saya tidak dapat menemukan cara untuk mendapatkan jumlah baris yang terpengaruh pada diberikan transaction_id
(sesuatu yang mirip dengan @@ROWCOUNT
mungkin, tetapi dengan transaction_id
argumen sebagai).
Saya mengerti bahwa pada SQL Server SELECT INTO-statement adalah pernyataan DDL dan DML dalam satu, dan karenanya, pembuatan tabel implisit akan menjadi operasi penguncian. Saya masih berpikir harus ada cara pintar untuk mendapatkan semacam informasi kemajuan saat pernyataan sedang berjalan.
Jawaban:
Saya curiga bahwa
rows
dalamsys.partitions
0 karena belum berkomitmen. Tetapi ini tidak berarti bahwa SQL Server tidak mengetahui apa yang akan terjadi jika Transaksi melakukan. Kuncinya adalah mengingat bahwa semua operasi melewati Buffer Pool (yaitu memori) terlebih dahulu, terlepas dari COMMIT atau ROLLBACK dari operasi. Karenanya, kita dapat mencarisys.dm_os_buffer_descriptors
info itu:Jika Anda ingin melihat detailnya, batalkan komentar pada baris pertama item dalam
SELECT
daftar, beri komentar pada 3 baris yang tersisa.Saya menguji dengan menjalankan berikut ini di satu Sesi dan kemudian berulang kali menjalankan kueri di atas di lain.
sumber
Satu atau tidak aktif?
Jika ini adalah kebutuhan yang dapat diantisipasi sebelumnya * Anda bisa menggunakan
sys.dm_exec_query_profiles
Koneksi 1 (sesi 55)
Koneksi 2
Anda mungkin perlu untuk jumlah baris jumlah kembali jika
SELECT INTO
sudah menggunakan paralelisme .* Sesi yang ingin Anda monitor menggunakan DMV ini harus diaktifkan untuk pengumpulan statistik menggunakan
SET STATISTICS PROFILE ON
atauSET STATISTICS XML ON
. Meminta rencana eksekusi "aktual" dari SSMS juga berfungsi (karena menetapkan opsi yang terakhir).sumber
Saya tidak berpikir ada cara untuk mendapatkan jumlah baris, tetapi Anda dapat memperkirakan jumlah data yang ditulis dengan melihat:
Jika Anda memiliki beberapa gagasan tentang berapa banyak halaman yang harus diambil ketika selesai, Anda harus dapat menyelesaikan%. Kueri yang terakhir tidak akan cepat karena tabel semakin besar. Dan mungkin paling aman untuk menjalankan di bawah
READ UNCOMMITTED
(dan tidak sering saya merekomendasikan itu, untuk apa pun).sumber
Jika Anda dapat mengubah
INSERT
darike a
maka
select count(*) from DestTable with (nolock)
permintaan Anda akan berhasil.Jika ini tidak memungkinkan maka Anda dapat menggunakan sp_WhoIsActive (atau mempelajari DMV) untuk memantau berapa banyak penulisan yang dilakukan kueri. Ini akan menjadi ukuran yang agak kasar tetapi bisa berguna jika Anda mendasarkan jumlah tulisan yang biasanya.
Anda harus bisa mendapatkan minimal logging dengan yang di
INSERT
atas jika Anda menambahkanWITH (TABLOCK)
.sumber
INSERT
atas jika Anda menambahkanWITH(TABLOCK)
BULK_OPERATION
kunci.