Variasi besar dalam waktu Masukkan Massal


13

Jadi saya punya proses Sisipkan Massal sederhana untuk mengambil data dari tabel pementasan kami dan memindahkannya ke datamart kami.

Prosesnya adalah tugas aliran data sederhana dengan pengaturan default untuk "Baris per batch" dan opsinya adalah "tablock" dan "no check constraint".

Meja cukup besar. 587.162.986 dengan ukuran data 201GB dan ruang indeks 49GB. Indeks berkerumun untuk tabel adalah.

CREATE CLUSTERED INDEX ImageData ON dbo.ImageData
(
    DOC_ID ASC,
    ACCT_NUM ASC,
    MasterID ASC
)

Dan Kunci Utama adalah:

ALTER TABLE dbo.ImageData 
ADD CONSTRAINT ImageData 
PRIMARY KEY NONCLUSTERED 
(
    ImageID ASC,
    DT_CRTE_DOC ASC
)

Sekarang kami mengalami masalah di mana BULK INSERTvia SSIS berjalan sangat lambat. 1 jam untuk memasukkan sejuta baris. Permintaan yang mengisi tabel sudah diurutkan dan permintaan untuk mengisi membutuhkan waktu kurang dari satu menit untuk berjalan.

Ketika proses ini berjalan saya bisa melihat permintaan menunggu pada masukkan BULK yang memakan waktu antara 5 hingga 20 detik dan menunjukkan jenis menunggu PAGEIOLATCH_EX. Prosesnya hanya mampu INSERTsekitar seribu baris sekaligus.

Kemarin saat menguji proses ini terhadap lingkungan UAT saya, saya mengalami masalah yang sama. Saya sedang menjalankan proses beberapa kali dan mencoba untuk menentukan apa penyebab utama dari penyisipan yang lambat ini. Kemudian tiba-tiba mulai berjalan dalam waktu kurang dari 5 menit. Jadi saya menjalankannya beberapa kali lagi dengan hasil yang sama. Juga jumlah sisipan massal yang menunggu 5 detik atau lebih besar dari ratusan turun menjadi sekitar 4.

Sekarang ini membingungkan karena tidak seperti kami memiliki beberapa penurunan besar dalam aktivitas.

CPU selama durasinya rendah.

CPU

Saat-saat ketika lebih lambat tampaknya lebih sedikit menunggu pada disk.

Menunggu

Disk latensi sebenarnya meningkat selama kerangka waktu proses berjalan di bawah 5 menit.

Latensi

Dan The IO jauh lebih rendah pada saat proses ini berjalan buruk.

IO

Saya sudah memeriksa dan tidak ada pertumbuhan file karena file hanya 70% penuh. File log masih memiliki 50% lagi. DB dalam mode Pemulihan Sederhana. DB hanya memiliki satu grup file tetapi tersebar di 4 file.

Jadi apa yang saya bertanya-tanya A: mengapa saya melihat waktu tunggu yang begitu besar pada sisipan massal tersebut. B: Sihir macam apa yang terjadi yang membuatnya berjalan lebih cepat?

Catatan samping. Ini berjalan seperti omong kosong lagi hari ini.

PEMBARUAN saat ini dipartisi. Namun itu dilakukan dalam metode yang paling konyol.

CREATE PARTITION SCHEME [ps_Image] AS PARTITION [pf_Image] 
TO ([FG_Image], [FG_Image], [FG_Image], [FG_Image])

CREATE PARTITION FUNCTION [pf_Image](datetime) AS 
RANGE RIGHT FOR VALUES (
      N'2011-12-01T00:00:00.000'
    , N'2013-04-01T00:00:00.000'
    , N'2013-07-01T00:00:00.000'
);

Ini pada dasarnya meninggalkan semua data di partisi ke-4. Namun karena itu semua akan ke grup file yang sama. Data saat ini dibagi secara merata di seluruh file-file itu.

UPDATE 2 Ini adalah keseluruhan menunggu saat proses berjalan buruk.

Tunggu 1

Ini adalah menunggu selama periode yang saya dapat menjalankan proses berjalan dengan baik.

Tunggu2

Subsistem penyimpanan adalah RAID yang terpasang secara lokal, tidak ada SAN yang terlibat. Log berada di drive yang berbeda. Raid Controller adalah PERC H800 dengan ukuran cache 1 GB. (Untuk UAT) Prod adalah PERC (810).

Kami menggunakan pemulihan sederhana tanpa cadangan. Ini dipulihkan dari salinan produksi setiap malam.

Kami juga telah menetapkan IsSorted property = TRUESSIS karena data sudah diurutkan.


ASYNC_NETWORK_IOberarti SQL Server sedang menunggu pengiriman baris ke klien di suatu tempat. Saya kira itu menunjukkan aktivitas SSIS mengkonsumsi baris dari tabel pementasan.
Max Vernon

PAGEIOLATCH_EXdan ASYNC_IO_COMPLETIONmenunjukkan sedang mengambil data dari disk ke dalam memori. Ini bisa menjadi indikator masalah dengan subsistem disk, atau mungkin pertengkaran memori. Berapa banyak memori yang tersedia SQL Server?
Max Vernon

Dengan nama tabel ImageData, Anda ingin tahu saya - apa definisi tabel sebenarnya? Jika Anda menarik data LOB, Anda mungkin telah buffering ke disk (yang pergi ke BLOBTempStoragePath yang jika tidak terdefinisi akan menjadi pengguna% TEMP% direktori alias drive C drive)
billinkc

Tidak dapat memposting definisi tabel tetapi informasinya adalah dokumen gambar.
Zane

Saya menduga itu adalah masalah pemrosesan paralel. Saya sarankan Anda untuk menyetel MAXDOP Anda (mulai dari 1 hingga 4) dan melihat bagaimana semuanya berjalan. Di sisi lain, untuk tujuan pengujian, saya lebih suka membuat perintah BCP untuk menggantikan SSIS dan melihat apakah ada perbedaan.
jyao

Jawaban:


1

Saya tidak dapat menunjukkan penyebabnya, tetapi saya percaya baris default-per-batch untuk operasi BULK INSERT adalah "semua". Menetapkan batas dalam baris dapat membuat operasi lebih mudah dicerna: itu sebabnya ini merupakan pilihan. (Di sini dan terus, saya sedang melihat dokumentasi "BULK INSERT" Transact-SQL, sehingga bisa jadi jalan keluar untuk SSIS.)

Ini akan memiliki efek membagi operasi menjadi beberapa batch X rows, masing-masing beroperasi sebagai transaksi terpisah. Jika ada kesalahan, kumpulan yang selesai akan tetap berkomitmen ke tabel tujuan, dan kumpulan yang dihentikan akan rollback. Jika itu lumayan dalam apa yang Anda lakukan, yaitu Anda dapat menjalankannya kembali nanti dan mengejar ketinggalan, maka, coba itu.

Tidak salah untuk memiliki fungsi partisi yang menempatkan semua sisipan saat ini ke dalam satu tabel partisi, tapi saya tidak melihat bagaimana itu berguna untuk mempartisi sama sekali dengan partisi di filegroup yang sama. Dan menggunakan datetime buruk, dan sebenarnya agak rusak untuk datetime dan 'YYYY-MM-DD' tanpa rumus CONVERT eksplisit sejak SQL Server 2008 (SQL mungkin dengan senang hati memperlakukan ini sebagai YYYY-DD-MM: jangan bercanda: jangan panik, jangan panik, ubah saja ke 'YYYYMMDD', diperbaiki: atau CONVERT (datetime, 'YYYY-MM-DDT00: 00: 00', 126), saya pikir itu dia). Tapi saya pikir menggunakan proxy untuk nilai tanggal (tahun sebagai int, atau tahun + kuartal) untuk mempartisi akan bekerja lebih baik.

Mungkin itu desain yang disalin dari tempat lain, atau digandakan di beberapa datamarts. Jika ini -adalah datamart sejati, dump dari gudang data untuk memberi manajer departemen beberapa data untuk bermain, itu tidak (oleh Anda) dikirim di tempat lain, dan mungkin hanya-baca sejauh yang menyangkut pengguna data , kemudian, menurut saya Anda dapat menghapus fungsi partisi -atau- mengubahnya untuk secara eksplisit memasukkan semua data baru ke partisi keempat tidak peduli apa pun, dan tidak ada yang peduli. (Mungkin Anda harus memeriksa bahwa tidak ada yang peduli.)

Rasanya seperti desain di mana rencananya adalah untuk menjatuhkan konten partisi 1 beberapa waktu di masa depan dan membuat partisi baru untuk lebih banyak data baru, tetapi sepertinya itu tidak terjadi di sini. Setidaknya itu belum terjadi sejak 2013.


0

Saya telah melihat kelambatan ekstrim sporadis yang sama pada sisipan ke tabel dipartisi besar pada kesempatan sendiri. Sudahkah Anda mencoba memperbarui tabel tujuan Statistik dan kemudian berjalan lagi? Waktu tunggu ekstrem bisa disebabkan oleh statistik yang buruk, dan jika pembaruan stat dipicu pada beberapa titik selama pengujian Anda, maka itu akan menjelaskan peningkatan kecepatan. Hanya pemikiran dan tes mudah untuk diverifikasi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.