Cara terbaik untuk mengimpor kembali sejumlah besar data dengan downtime minimal

11

Saya perlu mengimpor sekitar 500.000 catatan yang berisi data pencarian IP (baca-saja referensi) sekitar seminggu sekali (hanya tiga int / bigint cols).

Saya tidak benar-benar ingin khawatir tentang penggabungan data dengan tabel yang ada, saya lebih suka membersihkan yang lama dan mengimpor kembali.

Idealnya kueri yang melebihi data akan terus berjalan (kami tidak mendapatkan banyak dari ini dan itu dapat diterima bagi mereka untuk menjalankan sedikit lebih lambat ketika impor terjadi, tetapi perlu sampai 24/7, jadi jalankan ini " di luar jam "bukan pilihan).

Hal-hal yang Sudah Dicoba Sejauh ini

SSIS: Saya telah membuat paket SSIS yang memotong tabel dan mengimpor - dibutuhkan sekitar 30 detik untuk berjalan (terlalu lama sebenarnya).

Tabel Temp: Mengimpor ke tabel temp, memotong dan menyalin seluruh juga membutuhkan waktu sekitar 30 detik.

BCP: Impor Massal juga agak terlalu lambat (untuk beberapa alasan lebih lambat daripada SSIS (bahkan tanpa indeks untuk mempertahankan) - Saya menduga itu ada hubungannya dengan transaksi char-> int / bigint: /

Meja cermin? Jadi, saat ini, saya bertanya-tanya tentang membaca tabel melalui tampilan, mengimpor data ke tabel cermin, dan mengubah tampilan untuk menunjuk ke tabel ini ... sepertinya ini akan cepat, tetapi tampaknya kecil sedikit hacky bagiku.

Sepertinya ini adalah masalah umum, tetapi saya tidak dapat menemukan praktik yang disarankan - ide apa pun akan sangat dihargai!

Terima kasih

Menandai
sumber

Jawaban:

13

Solusi yang pernah saya gunakan di masa lalu (dan telah merekomendasikan di sini dan di StackOverflow sebelumnya) adalah membuat dua skema tambahan:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Sekarang buat meniru tabel Anda di cacheskema:

CREATE TABLE cache.IPLookup(...columns...);

Sekarang ketika Anda melakukan operasi sakelar:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

Ini akan lebih rumit jika Anda memiliki kunci asing dan dependensi lainnya (karena Anda mungkin harus menghapusnya dan membuat ulang), dan tentu saja itu benar-benar membuat statistik tidak valid, dll. Dan ini, pada gilirannya, dapat memengaruhi rencana, tetapi jika yang paling penting adalah mendapatkan data yang akurat di depan pengguna Anda dengan gangguan minimal, ini bisa menjadi pendekatan untuk dipertimbangkan.

Aaron Bertrand
sumber
Terima kasih, alternatif lain yang menarik - Saya pikir dua pernyataan terakhir tidak tepat, harus memindahkan bayangan ke cache, dan memotong cache. Saya ingin tahu apakah Sinonim juga dapat digunakan?
Tandai
Anda benar, saya membuat mereka bingung. Saya tidak yakin persis bagaimana sinonim akan lebih baik, saya kira itu juga pendekatan - memiliki pandangan yang mengarah ke sinonim, dan mengubah sinonim yang mendasari dalam transaksi ketika Anda telah mengisi versi lain. Secara pribadi saya menemukan ini sedikit lebih baik - ketika Anda meminta dbo.IPLookup Anda tahu itu tabel "saat ini" tanpa harus mengejar tampilan dan sinonim.
Aaron Bertrand
FYI Saya menulis blog tentang ini lebih detail minggu ini: sqlperformance.com/2012/08/t-sql-queries/…
Aaron Bertrand