2011-05-14 30 views
7

'daki çok büyük tabloların UPDATE veya MERGE değerlerinin çok büyük (300M kayıtları) ve geniş bir TABLE1 günlük güncelleştirmesi gerçekleştirmeliyim. Güncelleştirmelerin kaynak verileri, TABLE1 satırlarının% 10 -% 25'i olan ancak UTABLE numaralı başka bir tabloda bulunur, ancak dardır. Her iki tablonun da birincil anahtar olarak record_id vardır.SQL Server

Halen, aşağıdaki yaklaşım kullanarak TABLE1 yeniden ediyorum:

<!-- language: sql --> 
    1) SELECT (required columns) INTO TMP_TABLE1 
    FROM TABLE1 T join UTABLE U on T.record_id=U.record_id 
    2) DROP TABLE TABLE1 
    3) sp_rename 'TMP_TABLE1', 'TABLE1' 

Ancak bu benim sunucuya (SQL Server için RAM 60GB) üzerine yaklaşık 40 dakika sürer. % 50 performans artışı elde etmek istiyorum - başka hangi seçenekleri deneyebilirim?

  1. MERGE ve UPDATE - kod aşağıda daha hızlı sadece çok küçük UTABLE tablo için çalışır gibi bir şey - tam boyutta, her şey sadece asılı:

    <!-- language: SQL --> 
    MERGE TABLE1 as target 
    USING UTABLE as source 
    ON target.record_id = source.record_id 
        WHEN MATCHED THEN 
        UPDATE SET Target.columns=source.columns 
    
  2. ben toplu gerçekleştirebilir duydum ROWCOUNT kullanarak MERGE - ama 300M satır tablosu için yeterince hızlı olabileceğini düşünmüyorum.

  3. Yardımcı olabilecek herhangi bir SQL sorgusu var mı?

+0

sırasında ek çalışmanın ek çalışmasına neden olacağından, lütfen TABLE1 dizinlemesinden kaçının. Sorgu planını gönderebilir misiniz? –

+0

Merhaba @chris, sorgu planı son derece basit: ** 1 ** Tablo Tarama TABLO1, ** 2 ** Tablo Tarama Sırası, ** 3 ** HASH JOIN, ** 4 ** MERGE. İlk ve Son adım, zamanın% 90'ını alıyor. Ancak, daha önce sorumu nasıl ele alacağımı anladım - lütfen kendi cevabımı görün. –

cevap

5

i genel böyle bir sorguları için öneriler öğrendim tablo (yani 240M).

Sorgunun sorgu planına baktığımızda TABLE1 TABLE SCAN ve son MERGE'un zamanın% 90'ını aldığını söyleyebiliriz.

MERGE TABLE1 as Target 
USING UTABLE as source 
ON Target.record_id = source.record_id 
WHEN MATCHED AND (condition) THEN 
    UPDATE SET Target.columns=source.columns 

Yani MERGE kullanmak için biz gerekir:

  1. biz güncellemek ve doğru olarak SQL Server bu bilgileri geçmesi gerekiyor satır sayısını azaltın. Bu, UTABLE daha küçük yapılarak ya da birleştirilecek parçayı daraltan ek condition belirtilerek yapılabilir.
  2. Birleştirilecek parçanın belleğe sığdığından emin olun, aksi halde sorgu yavaş çalışır. TABLE1'u iki kez daha az yapmak, gerçek sorgulama süremi 11 saatten 40 dakikaya düşürdü.

Mark-birleştirilecek-Sizin UPDATE sözdizimini kullanın ve bir kısmını daraltmak için WHERE maddesini kullanabilir belirtildiği gibi - bu aynı sonuçları verecektir. Ayrıca, MERGE

6

İlk bakışta darboğazınızın nerede olduğunu bulabilirim - CPU'nuz sabit veya boşta mı? Başka bir deyişle - IO alt sisteminiz yükü düzgün bir şekilde halledebilir mi?

Tam tablonun yeniden oluşturulması çok fazla IO yüküdür, temelde tablonun geçici olarak iki kez depolanması için çok yer kaplayacağından bahsetmemelidir.

Basit bir güncelleştirmenin yeterli olmasını sağlayabildiğim noktadan bir MERGE gerçekleştirmeniz gerekiyor mu? Örnek:

Sen ROWCOUNT kullanarak güncellemeleri ancak yürütme hızlandırmak olmayacak kadar toplu, sadece genel kilitleme azaltılması ile yardımcı olacağız olabilir
UPDATE 
    TABLE1 
SET 
    ColumnX = UTABLE.ColumnX 
    ... 
FROM 
    TABLE1 
INNER JOIN 
    UTABLE ON TABLE1.record_id = UTABLE.record_id 

.

Ayrıca - masanın üzerinde ne tür dizinler var? Güncellemeden önce dizinleri devre dışı bırakmak ve daha sonra bunları sıfırdan (daha sonra kümelenmemiş) yeniden oluşturmak daha hızlı olabilir. SQL Birleştirme Kullanarak Fikir veya Güncelleme çok zeki biri ama biz büyük ve geniş çok sayıda kayıt (yani 75M) güncellemek için gerektiğinde başarısız: Aslında

+0

Merhaba İşareti, yanıt için teşekkürler, bir dizinim yok çünkü sadece MERGE veya UPDATE sorgularını yavaşlatabilir. IO'ya göre - Ortalama Disk Kuyruğuna dayalı sayaç diski oldukça yoğun ve TABLE1 bellekte uymuyor gibi görünüyor. Şimdi CTE ile ön filtreleme girişini deneylerim ve sadece sonra MERGE işlemini gerçekleştiririm. –

+1

+1 Harika cevap. Henüz kimsenin neden bu kadar endişelenmediğini anlayamıyorum. –