Milyonlarca kayıt içeren bir tabloyu güncelleme, 4 gün oldu


12

Şu anda milyonlarca kayıt içeren bir tabloyu güncelliyor, 4 gün oldu ve sorgu hala yürütülüyor.

Ben aktivite monitör sorgu çalıştığını gösterir kontrol ettim.

Olay günlüğünde hiç hata yok.

Performans açısından:

  • A diskindeki Tempdb (850 gb boş alan)
  • B diskindeki veritabanı dosyası (750 gb boş alan)
  • 16 GB RAM

Lütfen bana ne yapmam gerektiğini öner.

Sorgu

UPDATE
    dbo.table1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
    dbo.table2 t2
WHERE
    LEFT(dbo.test1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

Yanıtlar:


3

İlk başta fark etmedim bu sorgu ilginç bir ayrıntı var. Fabricio Araujo'ın cevabı sayesinde şimdi görüyorum: iki tabloya erişiyorsunuz. Daha önce güncelleme ifadesinin bu tür kullanımını hiç görmedim ve bunu kullanmanızı önermiyorum. Fabricio'nun yanıtı başına daha sezgisel birleştirme sözdizimi kullanmanızı öneririz.

Muhtemel neden, iki tablo arasındaki birleştirmenin çok sayıda satır üretmesidir. LEFT(col, 3)İfade yinelenen değerler üretirse bu olabilir . Eğer 10 kopya üretirse, birleştirme sonucunda 100000x100000 = 10000000000 satır elde edilir.

Endekslemenin burada bir rol oynadığını düşünmüyorum. SQL Server bu unindexed birleştirmeyi bir karma veya birleştirme birleştirme ile gayet iyi çözebilir. 4 gün sürmez.

Diğer olası neden, birleştirme girişlerinin veya çıkışlarının bir kardinalite az tahminidir. SQL Server bir döngü birleştirmeyi seçmiş olabilir.

Bu hala spekülasyon olduğu için, bu konuya ışık tutacak olan sorgu planını göndermenizi tavsiye ederim.


8

Bu sorgu tablodaki her satırı taramanızı gerektiriyor çünkü

  • Procodet veya ProviderCode dizine alınmamış sanırım
  • Endekslenmiş olsalar bile, WHERE yükleminde bir işlev olan bir SOL'unuz var
  • Ve bir WHERE yükleminde etkili bir işlev olan COLLATE de var

"WHERE yüklemindeki bir işlev", dizinlerin kullanılmayacağı anlamına gelir

Eğer toplu iş yaparsanız (GÜNCELLEŞTİR ÜST (10000) 'de söyleyin ... VE maliyet Yüzdesi NULLDİR) o zaman maliyet Yüzdesi konusunda bir dizine ihtiyacınız vardır ve bu ayarladığınızı varsayar.

Gördüğüm tek çözüm

  • yeni bir tabloyu, örneğin birincil anahtara göre gruplar halinde doldurma
  • LEFT ve COLLATE ifadelerini gizlemek için dizinlenmiş, hesaplanmış sütunlar oluşturun, ardından güncellemeyi çalıştırın

@ gbn .. teşekkürler bu harika bir fikir .. ama veri milyonlarca olduğu gibi bu işlem zaman alacaktır .... ben sorgu ilerlemesini bulmak için bir yolu olabilir diye düşünüyordum?
Şanslı

1
"Milyonlarca" satırı taramak neden 4 gün sürüyor? Satırlar ne kadar büyük ve ağır bir şekilde dizine eklenmiş olursa olsun, bu 4 gün sürmemelidir. Sorunun kökü hala bilinmiyor.
usr

1
Düzenli olarak büyük verilerle ilgilenirseniz, bunun için uygun bir sunucunuz olur mu? Verileri SSD'ye vb. Koyun.
TomTom

1
@ Şanslı. Cevabı ele alıyordum. Henüz bulamadığımız bir yanlışlık var. Tek başına veya donanımdan gelen sorgu değildir. Bu asla 4 gün sürmez.
usr

3
Sorgunun bir sütunun 3 karakterlik kısmını başka bir sütunun 3 karakterlik kısmına kattığı göz önüne alındığında, sonuç büyük olasılıkla kopyaları içerecektir. Bu sadece milyonlarca satırı güncellemekten çok daha kötüdür. Ben milyarlarca çalışma masası üzerinden tarama bahse girerim.
datagod

4

Her şeyden önce, sorguyu şu şekilde değiştirin:

UPDATE t1
SET 
    costPercentage = ISNULL(t2.PaymentIndex, 1.0),
    t2.TopUp_Amt = (ISNULL(t2.PaymentIndex, 1.0) - 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00),
    Total_Tariff_Inc_t2 = ISNULL(t2.PaymentIndex, 1.0)
    * ISNULL(dbo.table1.Initial_Tariff_Amt, 0.00)
FROM
  dbo.table1 t1
  inner join dbo.table2 t2
    on LEFT(t1.procodet, 3) = LEFT(t2.ProviderCode, 3) COLLATE database_default 

Jeff Moden'in bu tartışmadaki ilk gönderisinin belirttiği gibi, sorgunuz "Cadılar Bayramı efekti" konusunda uyardığına çok benziyor.

Bundan sonra, bu SOL ifadeler dizine eklenmelidir. gbn'nin cevabı size bunun nasıl yapılacağına dair işaretler verir.

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.