Birleştirme Fiziksel İşlem: Yürütme sırasını garanti ediyor mu?


12

Standart SQL'de, a sonucunun union allherhangi bir sırada olacağı garanti edilmez. Yani, şöyle bir şey:

select 'A' as c union all select 'B'

Herhangi bir sırada iki satır döndürebilir (her ne kadar pratikte bildiğim herhangi bir veritabanında 'A', 'B'den önce gelir).

SQL Server'da bu, "birleştirme" fiziksel işlemi kullanılarak bir yürütme planına dönüşür.

Birleştirme işleminin girdilerini tarayacağını ve girdilerin mevcut kayıtlarını döndürdüğünü kolayca hayal edebiliyorum. Ancak, web'de ( burada ) aşağıdaki ifadeyi buldum :

Sorgu İşlemcisi bu planı işleçlerin planda görünme sırasına göre yürütür, ilki en üstte ve sonuncusu sondur.

Soru: Bu pratikte doğru mu? Bunun doğru olduğu garanti ediliyor mu?

Microsoft belgelerinde, girişlerin ilkinden sonuncuya doğru sırayla tarandığına dair herhangi bir referans bulamadım. Öte yandan, her çalıştırmayı denediğimde, sonuçlar girdilerin gerçekten sırayla işlendiğini göstermektedir.

Motorun aynı anda birden fazla girişi işlemesinin bir yolu var mı? Testlerim (sabitlerden çok daha karmaşık ifadeler kullanarak) paralel özellikli 8 çekirdekli bir makinede yapılır ve çoğu sorgu paralellikten yararlanır.

Yanıtlar:


10

Hayır , Microsoft'tan davranışı garanti eden hiçbir belge yoktur, bu nedenle garanti edilmez .

Ayrıca, Basit Konuşma makalesinin doğru olduğunu ve Birleştirme fiziksel operatörünün girdileri her zaman planda gösterilen sırada (doğru olması muhtemel) işlediğini varsayarak, SQL Server'ın her zaman aynı tutan planlar üreteceğini garanti etmeden sorgu metni ve sorgu planı arasındaki sipariş, biraz daha iyi durumda.

Bunu daha ayrıntılı bir şekilde araştırabiliriz. Sorgu iyileştirici, Birleştirme operatörü girişini yeniden sıralayabiliyorsa, sys.dm_exec_query_transformation_statsbu optimizasyona karşılık gelen belgelenmemiş DMV'de satırlar olmalıdır .

SELECT * FROM sys.dm_exec_query_transformation_stats 
    WHERE name LIKE '%CON%' OR name LIKE '%UNIA%'

SQL Server 2012 Enterprise Edition'da bu 24 satır üretir. Sabitler ile ilgili dönüşümler için yanlış eşleşmeleri göz ardı ederek, Zincirleme Fiziksel İşleci UNIAtoCON(Tümünü Birleştirme ile Birleştirme) ile ilgili bir dönüşüm vardır . Dolayısıyla, fiziksel operatör düzeyinde, bir birleştirme operatörü seçildikten sonra, türetildiği mantıksal Union All operatörünün sırasına göre işleneceği anlaşılmaktadır.


Aslında bu tam olarak doğru değil. Maliyete dayalı optimizasyon tamamlandıktan sonra girdileri fiziksel bir Zincirleme işlecine yeniden sıralayabilen optimizasyon sonrası yeniden yazma işlemleri mevcuttur. Bir örnek, Birleştirme bir satır hedefine tabi olduğunda ortaya çıkar (bu nedenle önce daha ucuz girdiden okumak önemli olabilir). Daha fazla bilgi için Paul White'ın UNION ALLOptimizasyonu bölümüne bakınız.

Bu geç fiziksel yeniden yazma işlemi SQL Server 2008 R2'ye kadar ve bu işlev dahil olmak üzere işlevseldi, ancak bir gerileme artık SQL Server 2012 ve sonraki sürümlere uygulanmadığı anlamına geliyordu. Sorgu iyileştirici düzeltmeleri etkinleştirilmiş olarak SQL Server 2014 ve sonraki sürümleri (2012 değil) için bu yeniden yazmayı eski durumuna getiren bir düzeltme yayınlanmıştır (örn. İzleme bayrağı 4199).


Ama Mantıksal Birlik hakkında Tüm operatör ( UNIA)? UNIAReorderInputsGirdileri yeniden düzenleyebilen bir dönüşüm var . Ayrıca mantıklı bir Birlik Tümünü UNIAtoCONve UNIAtoMERGE(Birleşecekleri Birlik Birliği) uygulamak için kullanılabilecek iki fiziksel işleç de vardır .

Bu nedenle, Sorgu iyileştirici görünür olabilir bir için girdi yeniden sıralama UNION ALL; ancak, ortak bir dönüşüm gibi görünmüyor ( UNIAReorderInputskolayca erişebildiğim SQL Server'ların sıfır kullanımı . Optimizer kullanımını sağlayacak koşulları bilmiyoruz UNIAReorderInputs; ancak bir plan kılavuzu veya kullanımı plan ipucu, yukarıda belirtilen satır hedefi fiziksel yeniden sıralanan girdiler kullanılarak oluşturulan bir planı zorlamak için kullanılır.

Motorun aynı anda birden fazla girişi işlemesinin bir yolu var mı?

Birleştirme fiziksel operatörü bir planın paralel bir bölümünde bulunabilir. Bazı zorluk ile, aşağıdaki sorguyu kullanarak paralel birleştirme ile bir plan üretmek mümkün:

SELECT userid, regdate  FROM (  --Users table is around 3mil rows
    SELECT  userid, RegDate FROM users WHERE userid > 1000000
    UNION 
    SELECT  userid, RegDate FROM users WHERE userid < 1000000
    UNION all
    SELECT userid, RegDate FROM users WHERE userid < 2000000
    ) d ORDER BY RegDate OPTION (RECOMPILE)

Yani, en katı anlamda, fiziksel Birleştirme operatörü girdileri daima tutarlı bir şekilde işlemektedir (ilk önce birinci, alt saniye); ancak, optimizer fiziksel operatörü seçmeden önce girişlerin sırasını değiştirebilir veya Birleştirme yerine Bir Birleştirme birleşimi kullanabilir.


8

Craig Freedman'a göre , birleştirme operatörü için yürütme sırası garanti edilmektedir.

MSDN bloglarında Sorgu Planlarını Görüntüleme blog yazısından :

Bir operatörün birden fazla çocuğu olduğunda, çocukların sırasının önemli olduğunu unutmayın. En üstteki çocuk ilk çocuk, en alttaki çocuk ikinci çocuktur. Birleştirme operatörü, çocukları bu sırayla işler.

Ve çevrimiçi kitaplardan Showplan Mantıksal ve Fiziksel Operatörler Referansı

Birleştirme fiziksel operatörünün iki veya daha fazla girişi ve bir çıkışı vardır. Birleştirme, ilk giriş akışından satırları çıkış akışına kopyalar, ardından her ek giriş akışı için bu işlemi tekrarlar.


Bu teklif aradığım şeye oldukça yakın. Belgelerin bu durumda paralel işlemeyi engellemesi hayal kırıklığı yaratıyor olsa da, bu sırayla yürütülmesini bu sırayla iade edilmeye atlamak istiyorum.
Gordon Linoff

2

Topluluk wiki yanıtı :

Karşı örnek üretemediğiniz sürece, gözlemlenen davranışların her zaman bir şekilde garanti edildiğini kanıtlayabileceğinizi bilmiyorum. Bunun yokluğunda, sonuçların döndürüldüğü sırayı düzeltmenin yolu elbette bir eklemektir ORDER BY.

Bir "düzeltme" olup olmadığını bilmiyorum veya bazı senaryolarda sorguların farklı bir sırayla işlendiğini gösterebilirseniz, bir düzeltme ihtiyacı var.

Herhangi bir açık, resmi belgenin olmaması bana bu konuda güvenmemeniz gerektiğini gösteriyor. Bu, SQL Server 2005'in optimize edicisinin piyasaya sürülmesinden 8 yıl önce ORDER BYbir görünümde ve sorun GROUP BYolmadan insanları başını belaya sokan şeydir ORDER BY.

SQL Server'ın yeni sürümlerindeki tüm yeni özelliklerle (daha fazlası ile), bugün belirli bir davranışı garanti edebileceğinizi düşünseniz bile, (bunu belgelendirilene kadar) doğru olmasını beklemem.

Bu davranışa bağlı olmasanız bile, sonuçlarla ne yapacaksınız? Her neyse, dışarıdan bir görevli tarafından Basit Konuşma makalesini çağırmam . Hepimiz biliyoruz ki bu sadece gözlem tabanlı bir tahmindir.

Microsoft hiçbir zaman 'x' 'y' yapacağının garanti edilmediğini söyleyen resmi belgeleri yayınlamayacaktır . Bu, neredeyse on yıl sonra, insanları gözlemlenen sıralamaya güvenemeyecekleri konusunda ikna etmekte zorlanmamızın nedenlerinden biridir ORDER BY- "garanti edilmediğini" belirten hiçbir belge yoktur.

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.