Saya perlu memperbarui 100 juta catatan dalam satu tabel, pada dasarnya, menormalkan tabel dengan mengganti nilai varchar dari sebuah kolom dengan hanya sebuah ID. (Saya mengatakan "mengganti" tetapi sebenarnya saya sedang menulis ID ke kolom lain.)
Apa yang saya coba capai adalah menormalkan dataset. Data yang belum dinormalisasi tidak memiliki indeks. Pikir saya adalah bahwa saya tidak akan membangun indeks pada nilai mentah, menunggu, alih-alih mengindeks kunci asing yang akan menggantikan nilai varchar dengan nilai tinyint setelah pembaruan selesai.
UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
Latar Belakang
- menggunakan MSSQL 2008 R2 pada Server 2008 R2
- server memiliki RAM 8 GB
- server memiliki satu RAID10, 7200 RPM SATA (tidak hebat, saya tahu, dalam produksi ini hanya akan membaca data dan tidak menulis data; ditambah kekurangan HD baru-baru ini membuat ini diperlukan untuk biaya)
- server memiliki CPU Xeon quad-core ganda
- mesin tidak melakukan hal lain (saat ini didedikasikan untuk dev, hanya proses ini)
- logging sederhana dihidupkan (? - tetapi apakah itu masih masuk sehingga dapat mengembalikan?)
- perhatikan bahwa kueri merujuk dua DB yang berbeda, untuk apa itu layak
- "Lebar" dari catatan dalam tabel yang diperbarui adalah 455 byte
Sumber Daya Selama Eksekusi
- RAM fisik sudah maksimal
- disk I / O sudah maksimal
- CPU hampir tidak melakukan apa-apa (choke point I / O)
- jangka waktu telah 14 jam dan terus bertambah!
Saya menduga beberapa hal seperti saya perlu indeks pada data mentah, meskipun saya akan menjatuhkan kolom (AutoClassName) setelah pembaruan normalisasi. Saya juga bertanya-tanya apakah saya seharusnya hanya mengulang tabel satu per satu daripada BERSAMA, yang tampak konyol pada saat saya memulai ini, tetapi sekarang tampaknya itu akan lebih cepat.
Bagaimana saya harus mengubah metodologi saya untuk pembaruan normalisasi yang tersisa (mirip dengan yang ini) lebih cepat?
sumber
TOP
klausa. Itu akan menjadi pendekatan saya.Saya akan mengambil pendekatan yang berbeda.
Alih-alih memperbarui tabel yang sudah ada, cukup buat tabel baru yang memiliki apa yang Anda butuhkan.
Ini hampir pasti akan lebih cepat:
Seperti yang ditulis saat ini, ada banyak operasi logis yang terjadi:
sumber
Melonggarkan meja satu baris sekaligus, tidak akan lebih cepat!
Seperti yang dicurigai, dan dikonfirmasi oleh Anda, ini akan terikat dengan I / o - memiliki satu disk, membaca, menulis, log transaksi, dan (apa saja) ruang kerja temp semua akan bersaing untuk i / o yang sama.
Pemulihan sederhana masih akan mencatat transaksi, tetapi log akan dihapus oleh pos pemeriksaan. Mungkin saja ukuran log awal Anda dan pengaturan pertumbuhan otomatis menyebabkan beberapa i / o melambat - log transaksi perlu tumbuh untuk mengakomodasi perubahan.
Sudahkah Anda mencoba mengindeks bidang AutoClassName? Berapa banyak nilai AutoClass yang berbeda?
Anda mungkin perlu mengelompokkan pembaruan, berdasarkan batasan i / o Anda. Jadi perbarui 1 juta, pos pemeriksaan, ulangi ....
sumber
Buat indeks untuk bidang yang bergabung.
Anda selalu dapat menjatuhkan indeks saat Anda selesai.
Saya akan sangat terkejut jika indeks tidak secara signifikan meningkatkan kinerja pembaruan.
sumber
Ekspor seperti yang Anda inginkan, buat tabel baru dan impor kembali. Sebagai Bonus, Anda akan memiliki salinan data sebagai cadangan, jika keajaiban terjadi.
sumber