Hesaplanan sütunlardaki Skaler UDF'lerin paralelliği engellemesini önlemenin bir yolu var mı?


29

SQL Server'daki Scalar UDF'lerin tehlikeleri hakkında çok şey yazıldı . Sıradan bir arama, sonuçların ipuçlarını döndürür.

Scalar UDF'nin tek seçenek olduğu bazı yerler var.

Örnek olarak: XML ile uğraşırken: XQuery hesaplanan sütun tanımı olarak kullanılamaz. Microsoft tarafından belgelenmiş bir seçenek kullanmaktır Skaler UDF skalar UDF içinde XQuery'yi saklanması ve sonra hesaplanan sütunda kullanabilirsiniz.

Bunun çeşitli etkileri ve bazı geçici çözümleri vardır.

  • Tablo sorgulandığında satır satır yürütür
  • Tüm sorguları tabloya karşı seri olarak çalıştırmaya zorlar

İşlevi düzenleyerek ve hesaplanan sütuna devam ederek veya dizine ekleyerek satır satır yürütme işleminin üstesinden gelebilirsiniz. Bu yöntemlerin hiçbiri skaler UDF'ye başvurulmasa bile, masaya vuran sorguların zorla seri hale gelmesini engelleyemez.

Bunu yapmanın bilinen bir yolu var mı?

Yanıtlar:


31

Evet eğer sen:

  • SQL Server 2014 veya sonraki sürümlerini çalıştırıyorsanız; ve
  • sorguyu 176 aktif izleme bayrağıyla çalıştırabilir ; ve
  • hesaplanan sütun PERSISTED

Spesifik olarak, en azından aşağıdaki versiyonlar gereklidir :

  • SQL Server 2016 SP1 için Toplu Güncelleştirme 2
  • SQL Server 2016 RTM için Toplu Güncelleştirme 4
  • SQL Server 2014 SP2 için Toplu Güncelleştirme 6

AMA bu düzeltmelerde ortaya konan bir hatayı önlemek için (ref için 2014 ve 2016 ve 2017 için ), bunun yerine aşağıdakileri uygulayın:

İzleme bayrağı, başlatma –Tseçeneği olarak, hem genel hem de oturum kapsamını kullanarak DBCC TRACEONve sorgu başına OPTION (QUERYTRACEON)veya bir plan kılavuzu ile etkilidir .

İzleme bayrağı 176, kalıcı bilgisayar sütun genişlemesini önler.

Bir sorgu derlerken gerçekleştirilen ilk meta veri yüklemesi, yalnızca doğrudan başvurulanları değil tüm sütunları getirir. Bu, hesaplanan tüm sütun tanımlarını eşleştirme için kullanılabilir kılar, bu genellikle iyi bir şeydir.

Talihsiz bir yan etki olarak, yüklenen (hesaplanan) sütunlardan biri skaler kullanıcı tanımlı bir işlev kullanıyorsa, varlığı hesaplanan sütun gerçekte kullanılmadığında bile tüm sorgu için paralelliğe izin vermez .

Izleme bayrağı 176, sütun devam ederse, tanım yüklenmeden (genişleme atlandığından) bu konuda yardımcı olur. Bu şekilde, derleme sorgu ağacında skalar kullanıcı tanımlı bir işlev hiçbir zaman bulunmaz, bu nedenle paralellik devre dışı bırakılmaz.

İzleme bayrağının (176) ana dezavantajı (yalnızca hafifçe belgelenmesi dışında), kalıcı ifadeli hesaplanmış sütunlarla eşleşen sorgu ifadesini de engellemesidir: Sorgu, kalıcı bir hesaplanmış sütuna uyan bir ifade içeriyorsa, izleme bayrağı (176) ifadenin yerine geçmesini önleyecektir. hesaplanan sütuna bir başvuru.

Daha fazla ayrıntı için, Düzgün Kalıcı Hesaplanan Sütunlar adlı SQLPerformance.com makaleme bakın .

Soru, hesaplanan sütun ve skaler işlevi kullanarak değerleri teşvik etmenin bir alternatifi olarak XML'den bahsettiği için, Seçici XML Dizinlerinde yazdığınız gibi, Seçici XML Dizini'ni de kullanabilirsiniz .


10

@ Paul'ün mükemmel Evet # 1'ine ek olarak , aslında Evet # 2 var:

  • SQL Server 2005’e kadar çalışır,
  • İzleme bayrağı ayarlamayı gerektirmez,
  • yok değil hesaplanan sütun olmasını gerektirir PERSISTEDve
  • (iz bayrağı 176 gerektirmeyen nedeniyle), etmez olmayan hesaplanan sütun kalıcı sorgu sentezleme eşlemeyi önlemek

Tek dezavantajları (söyleyebileceğim kadarıyla):

  • Azure SQL Veritabanında çalışmaz (en azından henüz olmasa da, Amazon RDS SQL Server'da ve Linux'ta SQL Server'da çalışsa da) ve
  • DBA’nın konfor bölgesinin biraz dışında

Ve bu seçenek: SQLCLR

Doğru. SQLCLR Skaler UDF biri serin yönü yani, eğer onlar yapmazlar herhangi veri erişimini (kullanıcı ne de sistem ne), o zaman onlar paralellik yasaklamıyor. Ve bu sadece teori ya da pazarlama değil. Tamamen ayrıntılı yazmayı yapmak için vaktim (şu anda) olmasa da, bunu test ettim ve kanıtladım.

İlk kurulumu aşağıdaki blog gönderisinden kullandım (umarım OP bunu güvenilmez bir kaynak olarak görmez):

Kötü Fikir Jeans: Çoklu Dizin İpuçları

Ve aşağıdaki testleri yaptım:

  1. İlk sorguyu ─⇾ Paralellik (beklendiği gibi) olduğu gibi çalıştır
  2. ([c2] * [c3])Paralelcilik (beklendiği gibi) olarak tanımlanan kalıcı bir hesaplanmış sütun eklendi.
  3. Hesaplanan sütun kaldırıldı ve ─⇾ NO Parallelism (beklendiği SCHEMABINDINGgibi) olarak tanımlanan bir T-SQL Skaler RETURN (@First * @Second);UDF'ye (birlikte oluşturulmuş ) başvuran başvuruda bulunmayan bir hesaplanmış sütun eklendi.
  4. T-SQL UDF hesaplanan sütun kaldırıldı ve ─⇾ Parallelism (woo hoo !!) olarak tanımlanan bir SQLCLR Skaler UDF'ye ( her ikisi IsDeterministic = trueve ile denenmiş = false) referans veren kalıcı bir hesaplanmış sütun eklendi.return SqlInt32.Multiply(First, Second);

Dolayısıyla, SQLCLR herkes için işe yaramazken, kesinlikle uygun olan insanlar / durumlar / ortamlar için avantajları vardır. Ve, bu belirli soru ile ilgili olduğu için - XQuery'nin kullanımıyla ilgili verilen örnek - bunun için kesin olarak işe yarayacaktır (ve özellikle ne yapıldığına bağlı olarak, biraz daha hızlı olabilir) 😎.

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.