Bir "TOP (X)" yan tümcesi ile bir SQL UPDATE deyimi var ve ben değerleri güncelleştiriyorum satır yaklaşık 4 milyar satır var. "TOP (10)" kullandığımda, neredeyse anında çalışan bir yürütme planı alıyorum, ancak "TOP (50)" veya daha büyük kullandığımda, sorgu asla (en azından beklerken değil) bitiyor ve tamamen farklı bir uygulama planı kullanır. Küçük sorgu, bir çift dizin araması ve iç içe döngü birleşimi içeren çok basit bir plan kullanır; burada aynı sorgu (UPDATE deyiminin TOP yan tümcesinde farklı sayıda satır içeren) iki farklı dizin araması içeren bir plan kullanır , bir masa makarası, paralellik ve bir dizi diğer karmaşıklık.
Ben daha küçük sorgu tarafından oluşturulan yürütme planı kullanmaya zorlamak için "SEÇENEK (KULLANIM PLANI ...)" kullandım - bunu yaptığımda, birkaç saniye içinde 100.000 kadar satır güncelleyebilirsiniz. Sorgu planının iyi olduğunu biliyorum, ancak SQL Server yalnızca bu planı yalnızca az sayıda satır bulunduğunda kendi başına seçecektir - güncellememdeki herhangi bir terbiyeli büyük satır sayısı en uygun planla sonuçlanacaktır.
Paralelliğin suçlanabileceğini düşündüm, bu yüzden MAXDOP 1
sorguyu ayarladım , ancak hiçbir etkisi yok - bu adım gitti, ancak kötü seçim / performans değil. Ben de sp_updatestats
bu sabah bunun sebebi olmadığından emin olmak için koştum .
İki yürütme planını ekledim - daha kısa olanı da daha hızlı olanı. Buna ek olarak, söz konusu sorgu (eklediğim SELECT'in hem küçük hem de büyük satır sayılarında hızlı olduğunu belirtmek gerekir):
update top (10000) FactSubscriberUsage3
set AccountID = sma.CustomerID
--select top 50 f.AccountID, sma.CustomerID
from FactSubscriberUsage3 f
join dimTime t
on f.TimeID = t.TimeID
join #mac sma
on f.macid = sma.macid
and t.TimeValue between sma.StartDate and sma.enddate
where f.AccountID = 0 --There's a filtered index on the table for this
Sorgumu ayarladığım şekilde ya da sorgu motorunun yaptığı kötü seçime kendini borçlu olduğu sürece yürütme planında bariz bir şey var mı? Gerekirse, ilgili tablo tanımlarını ve bunlarda tanımlanan dizinleri de ekleyebilirim.
Veritabanı nesnelerinin yalnızca istatistiki bir sürümünü isteyenlere: Bunu yapabileceğinizin farkında bile değildim, ama tam mantıklı! Başkaları için yürütme planlarını test edebilmek için sadece bir istatistik veritabanı için komut dosyaları oluşturmaya çalıştım, ancak filtrelenmiş dizinimde (komut dosyasında sözdizimi hatası gibi görünüyor) istatistik / histogram üretebilirim, bu yüzden ben şanssızlık. Filtreyi kaldırmayı denedim ve sorgu planları yakındı, ama tam olarak aynı değildi ve kaz kovalamacasında kimseyi göndermek istemiyorum.
Güncelleme ve bazı daha eksiksiz yürütme planları: Öncelikle SQL Sentry'nin Plan Gezgini inanılmaz bir araçtır. Hatta bu sitedeki diğer sorgu planı soruları görüntülenene kadar var olduğunu bilmiyordum ve benim sorgu yürütme hakkında söylemek biraz vardı. Sorunla nasıl başa çıkacağımdan emin olmasam da, sorunun ne olduğunu açıkça ortaya koydu.
İşte 10, 100 ve 1000 satır özeti - 1000 satırlı sorgunun diğerleriyle çizgiden çok uzak olduğunu görebilirsiniz:
Üçüncü sorgunun gülünç sayıda okuması olduğunu görebilirsiniz, bu yüzden tamamen farklı bir şey yapıyor. İşte satır sayısı ile tahmini yürütme planı. 1000 satırlık tahmini yürütme planı:
Ve işte yürütme planının asıl sonuçları (bu arada, "asla bitmez" derken, "bir saatte biter" demek istediğim ortaya çıktı). 1000 satır gerçek yürütme planı
Fark ettiğim ilk şey, dimTime tablosundan beklendiği gibi 60K satır çekmek yerine, aslında B ile 1.6 milyar çekiyor olmasıydı . Sorguma baktığımda, dimTime tablosundan bu kadar satır nasıl geri çektiğinden emin değilim. Kullandığım BETWEEN operatörü, Fact tablosundaki zaman kaydına dayalı olarak #mac'dan doğru kaydı almamı sağlıyor. Ancak, tek bir değere t.TimeValue (veya t.TimeID) süzdüğüm WHERE deyimine bir satır eklediğimde, saniyeler içinde 100.000 satırı başarıyla güncelleyebilirim. Bunun bir sonucu olarak ve dahil ettiğim yürütme planlarında da belirtildiği gibi, zaman çizelgemin sorun olduğu açık, ancak bu soruna geçici bir çözüm bulmak ve doğruluğu korumak için birleştirme ölçütlerini nasıl değiştireceğimi bilmiyorum . Düşüncesi olan var mı?
Başvuru için, burada 100 satır güncellemesi için plan (satır sayılarıyla birlikte). Aynı dizine ve hala bir ton sıraya sahip olduğunu, ancak hiçbir sorunun aynı büyüklüğüne yakın olmadığını görebilirsiniz. Satır sayıları ile 100 satır yürütme :
from #mac sma join f on f.macid = sma.macid join dimTime t on f.TimeID = t.TimeID and t.TimeValue between sma.StartDate and sma.enddate
vs vsfrom #mac join t on t.TimeValue between sma.StartDate and sma.enddate join f on f.TimeID = t.TimeID and f.macid = sma.macid
TOP 50
hala hızlı bir şekilde yürütülmelidir. XML planlarını yükleyebilir misiniz? Satır sayılarına bakmam gerekiyor. Çalıştırmak Can TOP 50
değil güncelleme olarak, MAXDOP 1 ile ve seçkin olarak ve planı sonrası? (Arama alanını basitleştirmeye / bölmeye çalışıyor).
t.TimeValue between sma.StartDate and sma.enddate
daha sonra FactSubscriber'e katılmak üzere filtrelenen ve sonuçta sonuçlanmayan çok daha fazla işe yaramaz satır üretebilir.
sp_updatestatistics
Masada bir koştun mu?