Pencere parametreleri 'where' yan tümcesi içeren bir görünümden çağrıldığında korkunç yürütme planına neden oluyor


10

Bu sorunu uzun zaman önce yaşadım, bana uygun bir çözüm buldum ve unuttum.

Ama şimdi SO ile ilgili bir soru var, bu yüzden bu sorunu gündeme getirmeye hazırım.

Birkaç tabloyu çok basit bir şekilde birleştiren bir görünüm var (siparişler + sipariş satırları).

whereMadde olmadan sorgulandığında , görünüm birkaç milyon satır döndürür.
Ancak, hiç kimse bunu böyle demez. Genel sorgu

select * from that_nasty_view where order_number = 123456;

Bu, 5 metreden yaklaşık 10 kayıt döndürür.

Önemli bir şey: görünüm rank(), görünümün her zaman sorgulandığı alanla tam olarak bölümlenmiş bir pencere işlevi içerir :

rank() over (partition by order_number order by detail_line_number)

Şimdi, bu görünüm tam olarak yukarıda gösterildiği gibi sorgu dizesindeki değişmez parametrelerle sorgulanırsa, satırları anında döndürür. Uygulama planı gayet iyi:

  • Endeksleri her iki tabloda da indeksleri kullanarak arayın order_number(10 satır döndürür).
  • Geri dönen küçük sonuç üzerinden pencereleri hesaplamak.
  • Seçme.

Ancak, görünüm parametreli bir şekilde çağrıldığında işler kötü olur:

  • Index scanendeksleri yok sayarak tüm tablolarda. 5m satır döndürür.
  • Büyük katılım.
  • Pencereleri tüm partitions (yaklaşık 500k pencereler) üzerinden hesaplama .
  • Filter 5 metreden 10 sıra almak.
  • seçmek

Bu, parametrelerin dahil olduğu tüm durumlarda olur. SSMS olabilir:

declare @order_number int = 123456;
select * from that_nasty_view where order_number = @order_number;

Excel gibi bir ODBC istemcisi olabilir:

select * from that_nasty_view where order_number = ?

Veya sql birleşimini değil, parametreleri kullanan başka herhangi bir istemci olabilir.

Pencere işlevi görünümden kaldırılırsa, parametrelerle sorgulanıp sorgulanmamasına bakılmaksızın mükemmel bir şekilde hızlı çalışır.

Geçici çözümüm, rahatsız edici işlevi kaldırmak ve daha sonraki bir aşamada yeniden uygulamaktı.

Ama ne verir? SQL Server 2008'in pencere işlevlerini işleme biçiminde gerçekten bir hata mı var?


order_number birincil anahtar mı? Sütun ve parametre veri türleri eşleşiyor mu?
gbn

order_numberbirincil anahtar değildir. Her int not nulliki tabloda da kümelenmemiş dizin ile.
GSerg

5
SQL Server 2005 bu alanda yüklem zorlama ile ilgili sorunlar vardı . Şimdi sabit olduklarını düşündüm. BTW TSQL örneğinizde parametre değil bir değişken kullanılır. Eklemek OPTION (RECOMPILE)yardımcı olur mu?
Martin Smith

1
@GSerg - Son olarak filtre ile ilgili kötü planda filtre içine tahmini 5 milyon satır ve gerçekle eşleşen tahmini 10 satır var? Eğer öyleyse, o zaman yüklem itme sorunu hala tam olarak çözülmemiş olabilir.
Martin Smith

Yanıtlar:


5

Bu uzun süredir devam eden bir sorun gibi görünüyor bir şekilde veya başka bir şekilde yenileme yüzeyin ve hala SQL Server 2012'de mevcut.

Bunu tartışan bazı yayınlar

SQL Server'ın 2012'ye kadar olan tüm geçerli sürümleri, filtreyi option(recompile), kullanılanlar dışında (2008+ ise) parametrelenmiş bir yüklem için sıra projesinin ötesinde bir bölümleme grubuna aktaramaz.

recompileİpucuna bir alternatif , sorguyu @ a1ex07 tarafından önerildiği gibi parametrelenmiş bir satır içi TVF kullanmak için yeniden yazmaktır)


Sadece SQL Server 2014'te de vardı
Guillaume86

3

Görünümü tablo değerli udf ile değiştirmeyi denerdim. Bu şekilde önce kayıtları filtreleyecek ve sonra pencere işlevini uygulayacaktır. Bu işlev tablo parametresini kabul edebilir, böylece order_numberiçine birden fazla geçiş yapabilirsiniz


Yine başka bir çözüm, evet. Yine de yapamadım çünkü tüm istemciler tablo değerli bir işlevi tüketemediler.
GSerg

Neden? % 100 emin değilim, ama tek ihtiyacınız olan sorguyu biraz değiştirmek gibi bir şeySELECT * FROM my_funct(12345)
a1ex07

Gereksinimlerden biri, sorgunun Excel kullanan son kullanıcılar tarafından sarf edilmesi (yani MS Query tarafından) ve MS Query en azından 2003'e kadar olan sürümlerde bunu yapmanıza izin vermeyecekti.
GSerg

it will filter records first, and then apply window functionyanlış. İnfaz için belirleyici bir emir yoktur
Remus Rusanu
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.