Çok sayıda satır eklemek için en hızlı yol nedir?


27

Dosyaları bir hazırlama tablosuna yüklediğim bir veritabanına sahibim, bu aşamalandırma tablosundan bazı yabancı anahtarları çözmek için 1-2 birleştirme işlemine sahibim ve sonra bu satırları son tabloya (ayda bir bölümü olan) ekliyorum. Üç aylık veriler için 3,4 milyar satır var.

Bu satırları final masasına yerleştirmenin en hızlı yolu nedir? SSIS Veri Akışı Görevi (kaynak olarak bir görünüm kullanan ve hızlı yük etkin olan) veya INTO SELECT ... komutunu ekleyerek mi? Veri Akışı Görevini denedim ve yaklaşık 5 saat içinde yaklaşık 1 milyar satır alabiliyorum (sunucuda 8 çekirdekli / 192 GB RAM) ve bu da bana çok yavaş geliyor.


1
Bölümler ayrı dosya gruplarında mı (ve farklı fiziksel disklerdeki dosya gruplarında mı)?
Aaron Bertrand

3
Gerçekten iyi bir kaynak Veri Yükleme Performansı Kılavuzu . Bu, yapabileceğiniz çok sayıda performans optimizasyonuna hitap eder , örneğin TF610'un etkinleştirilmesi , BCP OUT / IN, SSIS vb. Kullanımı. Tavsiyelere uymanız ve ortamınızda test etmeniz yeterlidir .
Kin Shah,

@Aaron evet, ayda bir dosya grubu, 12 san lun eklenmiş, böylece tüm janlar bir lun atarlar. Lun başına kaç tane disk alacağından emin değiliz ama bol olmalı.
nojetlag

Evet, ben gerçekten "disk seti" demek istedim ve muhtemelen doygun olabilen denetleyicilerden de bahsedebilirdim.
Aaron Bertrand

@Kin kılavuza bir göz attı, ancak eski görünüyor, "SQL Server hedefi, bir Integration Services veri akışından SQL Server'a veri toplu olarak yüklenmenin en hızlı yoludur. Bu hedef, SQL Server'ın tüm toplu yükleme seçeneklerini destekler - ROWS_PER_BATCH ." SSIS 2012'de daha iyi performans için OLE DB hedefini tavsiye ediyorlar.
nojetlag

Yanıtlar:


25

Ortak bir yaklaşım:

  1. Hedef tablodaki indeksleri / kısıtlamaları devre dışı bırakın / bırakın.
  2. INSERT dbo.[Target] WITH (TABLOCKX) SELECT ...
  3. Elbette, JNK’ya verilen krediyle, yukarıdaki nişlemlerini işlem günlüğü üzerindeki gerilimi azaltabilecek sıralı gruplar halinde yapabilirsiniz ve elbette bazı parti başarısız olursa, yalnızca o seriden başlamanız gerekir. Bununla ilgili blog yazdım (silmelere referans olarak, aynı temel kavramlar geçerli): http://www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes
  4. Hedef tablodaki indeksleri / kısıtlamaları yeniden etkinleştirin / yeniden yaratın (tüm işlemler için gerekli olmadıklarında bunlardan bazılarını erteleyebilirsiniz ve temel verileri hızlı bir şekilde çevrimiçi hale getirmek daha önemlidir).

Bölümleriniz fizikselse ve sadece mantıksal değilse, farklı süreçlerin aynı anda farklı bölümleri doldurmasını sağlayarak biraz zaman kazanabilirsiniz (elbette bu kullanamazsınız TABLOCK/ kullanamazsınız TABLOCKX). Bu, kaynağın, üst üste binme / kilitleme vb. Olmadan seçim yapan ve işlemin bu tarafını daha da yavaş hale getiren çoklu işlemlere uygun olduğunu varsayar (ipucu: kaynakta hedeflenen bölümlendirme şemasına uyan kümelenmiş bir dizin oluşturun).

Ayrıca, BCP OUT/BCP IN gibi çok daha ilkel bir şeyi düşünebilirsiniz .

Bu konuda yardımcı olmak için SSIS’e atlayacağımı bilmiyorum. Muhtemelen orada bazı verimlilikler var, ancak çabanın tasarrufları haklı çıkardığını bilmiyorum.


2
Verileriniz sıralanmadıysa, dizinleri (özellikle kümelenmiş dizin) göz ardı etmeyin. Dizini bırakmak ve kümelenmiş bir dizini yeniden oluşturmayı beklemek büyük bir hata olabilir, çünkü hem büyük disk alanına hem de çok fazla zamana mal olabilir. Böyle bir hatayı ilk gören ben değilim. Sqlmag.com/t-sql/… bu makalede "B Planı" açıklamasına bakın . Yazar aynı sorunu vardı.
jyao

10

Sorununuza SSIS perspektifinden bakmak, bunun çok uzun zaman almış olmasının sebebini birlikte kullanmamanız olduğunu düşünüyorum. Bu, SSIS boru hattını dolduran çok fazla satıra yol açabilir ve bunun sonucunda SSIS performansınızı engelleyebilir. Yapmanız gereken, her parti ayarı için satırlarınızı ve muhtemelen maksimum kesici uç boyutunuzu değiştirmektir. Şimdi bunu da belirlediğiniz şey SSIS sunucunuz için mevcut olan bellek miktarına bağlı mı? SQL Server örneğinizin disk hızı nedir? Bunu yapmanın en iyi yolu testtir. Örneğin, 10.000 kullanalım. Bu, sunucuya zamanında 10.000'lik bir toplu iş gönderir ve böylece boru hattınızın aşırı dolmasını önler ve bu sürecin daha hızlı çalışmasına yardımcı olur. Bu ayarlar OLEDB hedefinizde belirlenir.

OLEDB Hedef

Bu bir sorunsa, @AaronBertrand'ın önerdiği gibi yapmadan önce ve sonra bir SQL yürütme görevi de ekleyebilirsiniz, tabloya herhangi bir dizin veya kısıtlama ekleyip / tekrar ekleyin.


1
"Hızlı yükleme" nin DBA.SE'de başka bir yerde ne olduğuna dair mükemmel bir soru var: dba.stackexchange.com/questions/141430/… .
Tüm İşlemlerden Jon,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.