İşlev Performansı


46

Depolanmış prosedür performansı (eski makale) ve kullanılabilirliğin sorgulanabilir olduğu bir MySQL geçmişinden geldiğimde, PostgreSQL'i şirketim için yeni bir ürün için değerlendiriyorum.

Yapmak istediğim şeylerden biri, uygulama mantığının bir kısmını saklı yordamlara taşımak. Bu nedenle, özellikle performans tuzakları ile ilgili olarak PostgreSQL'de (9.0) işlevlerin kullanımıyla ilgili DO'lar ve Yapılmayacaklar (en iyi uygulamalar) için buradayım.


Performansla ilgili olmayan hiçbir şeyden bahsetmek istemiyor musunuz?
Jack Douglas

Chris Travers saklı prosedürler kullanılarak avantajları hakkında çok şey blogları, mesela burada: ledgersmbdev.blogspot.de/2012/07/... burada ve: ledgersmbdev.blogspot.de/2012/07/... sadece onun blog aracılığıyla yağsız olduğu bir Bu konuda çok ilginç makaleler.
a_horse_with_no_name

Yanıtlar:


51

Açıkçası, "saklı yordamlar" terimi , Postgres 11 ile tanıtılan Postgres'teki SQL prosedürlerine işaret eder.

Aynı zamanda neredeyse tamamen aynı olanı yapan fonksiyonlar da var ve bunlar başından beri oradaydı.

Fonksiyonlar ile LANGUAGE sqltemelde (her zaman içinde çalıştırmak ve dolayısıyla atom, düz SQL bir işlev ambalajında komutlarla sadece toplu dosyalarıdır tek işlem) kabul parametreler. Bir SQL işlevindeki tüm ifadeler bir kerede planlanmıştır ; bu, birbiri ardına bir ifadeyi çalıştırmaktan tamamen farklıdır ve kilitlerin alındığı sırayı etkileyebilir.

Daha fazlası için, en olgun dil PL / pgSQL ( LANGUAGE plpgsql) 'dir. İyi çalışıyor ve son on yılda her sürümde geliştirildi, ancak SQL komutları için en iyi yapıştırıcı görevi görüyor. Ağır hesaplamalar için tasarlanmamıştır (SQL komutları dışında).

PL / pgSQL işlevleri, hazırlanan ifadeler gibi sorguları çalıştırır . Önbelleğe alınmış sorgu planlarını yeniden kullanmak, bazı planlama ek yükünü keser ve eşdeğer SQL ifadelerinden biraz daha hızlı hale getirir; bu, koşullara bağlı olarak gözle görülür bir etki olabilir. Bu soruda olduğu gibi yan etkileri de olabilir:

Bu, hazırlanan açıklamaların avantajlarını ve dezavantajlarını taşır - kılavuzda tartışıldığı gibi . Düzensiz veri dağılımına ve değişken parametrelere sahip tablolardaki sorgular için, belirli parametreler için optimize edilmiş bir yürütme planından elde edilen kazanç yeniden planlama maliyetinden ağır basarsa dinamik SQL ile EXECUTEdaha iyi performans gösterebilir.

Postgres 9.2 genel uygulama planları oturum için hala önbelleğe alındığından, ancak kılavuzdan alıntı yapıldığından :

Bu, parametresiz hazırlanmış ifadeler için hemen gerçekleşir; Aksi halde, yalnızca beş veya daha fazla uygulama, tahmini maliyet ortalaması (genel gider dahil) genel plan maliyet tahmininden daha pahalı olan planları ürettikten sonra gerçekleşir.

(Ab) kullanmadan çoğu zaman her iki dünyanın da en iyisini elde ederiz (bazı ek yükler eklenir) EXECUTE. Ayrıntılar yenilikler PostgreSQL 9.2'de PostgreSQL Wiki'nin .

Postgres 12, genel veya özel planları zorlamak için ek sunucu değişkeniniplan_cache_mode sunar. Özel durumlar için dikkatli kullanın.

Sen olabilir büyük kazanmak sunucu tarafı fonksiyonları ile ek gidiş gezileri önlemek için uygulamadan veritabanı sunucusuna. Sunucunun bir kerede mümkün olduğunca çalışmasını sağlayın ve yalnızca iyi tanımlanmış bir sonuç döndürün.

Karmaşık işlevlerin, özellikle tablo işlevlerinin ( RETURNING SETOF recordveya TABLE (...)) iç içe geçmesinden kaçının . İşlevler, sorgu planlayıcısının optimizasyon engelleri olarak poz veren kara kutulardır. Planlamayı basitleştiren dış sorgu bağlamında değil, aynı zamanda mükemmel planlardan daha azına neden olabilecek şekilde ayrı ayrı optimize edilirler. Ayrıca, fonksiyonların maliyet ve sonuç büyüklüğü güvenilir bir şekilde tahmin edilemez.

İstisna Bu kuralın basit bir SQL fonksiyonları (vardır LANGUAGE sqledilebilir), "inlined" bazı ön şartlar yerine getirildiği takdirde - . Sorgu planlayıcısının bu sunumda Neil Conway (gelişmiş sayfalar) tarafından nasıl çalıştığı hakkında daha fazla bilgi edinin .

PostgreSQL'de bir fonksiyon her zaman otomatik olarak tek bir işlem içinde çalışır . Hepsi başarılı ya da hiçbir şey. Bir istisna olursa, her şey geri alınır. Ama hata işleme var ...

Fonksiyonlardır sebeplerinden biri de bu değil tam olarak "saklı yordamları" (bu terim yanlış yönlendiren, bazen kullanılır bile). Bazı komutlar gibi VACUUM, CREATE INDEX CONCURRENTLYya CREATE DATABASEda fonksiyonlar izin verilmez böylece, bir işlem bloğunun içinde çalışamaz. (Ne SQL prosedürlerinde, henüz Postgres 11'den beri. Bu daha sonra eklenebilir.)

Yıllar boyunca binlerce plpgsql işlevi yazdım.


2
@nhahtdh: "otomatik işlem" teknik bir terim değildir. Açıkça söylendikten sonra şimdi ne söylediğini söylemenin pek de şık bir yolu değildi. Hiç özerk bir işlem değil. "özerk" sadece benzer bir kelime olur.
Erwin Brandstetter

4
Buradan ve SO'dan derlenen cevaplarınız epik bir PostGreSQL en iyi uygulama el kitabı olabilir.
Davos

10

Bazı DO's:

  • PG ifadeleri sıraya sokabildiği için mümkün olduğunda işlev dili olarak SQL kullanın
  • IMMUTABLE / STABLE / VOLATILE'ı doğru kullanın, çünkü PG değişken değilse veya sabitse sonuçları önbelleğe alabilir
  • STRICT işlevini doğru kullanın, çünkü PG işlevi null işlevi yerine herhangi bir giriş null olursa null değerini döndürür.
  • SQL'i işlev dili olarak kullanamadığınızda PL / V8'i düşünün. Yaptığım bazı bilimsel olmayan testlerde PL / pgSQL'den daha hızlı
  • İşlem dışı gerçekleşebilecek daha uzun süren işlemler için LISTEN / NOTIFY öğesini kullanın
  • Sayfa bazında sayfa numaralandırmayı uygulamak için işlevler kullanmayı göz önünde bulundurun;
  • İşlevlerinizi birim testi yaptığınızdan emin olun.

PL / V8'in PL / pgSQL'den daha hızlı olduğu iddiasını ilk kez görüyorum. Bunu destekleyecek herhangi bir (yayınlanmış) rakamınız var mı?
a_horse_with_no_name

@ a_horse_with_no_name hayır, bilmiyorum. Dediğim gibi, birkaç bilimsel olmayan test yaptım. Çoğunlukla mantıklıydı, veri erişimi değildi. Xmas üzerinde birkaç tekrarlanabilir test yapmaya çalışacağım ve tekrar göndereceğim.
Neil McGuigan

@a_horse_with_no_name burada FizzBuzz plv8'e karşı plpgsql'e hızlı ve nemli bir örnek: blog.databasepatterns.com/2014/08/plv8-vs-plpgsql.html
Neil McGuigan

8

Genel olarak veritabanına hareketli uygulama mantığı konuşmak, daha hızlı olduğu anlamına gelir - sonuçta verilere daha yakın çalışacak.

Bağlam geçişi gerektirmediklerinden SQL dili işlevlerinin diğer dilleri kullananlardan daha hızlı olduğuna inanıyorum (ancak% 100 emin değilim) . Dezavantajı ise hiçbir prosedürel mantığa izin verilmemesidir.

PL / pgSQL , yerleşik dillerin en olgun ve özellik tamamlayıcısıdır - ancak performans için C kullanılabilir (yalnızca hesaplama açısından yoğun işlevlerden faydalanmasına rağmen)


7

Postgresql'de kullanıcı tanımlı fonksiyonlar (UDF) kullanarak çok ilginç şeyler yapabilirsiniz. Örneğin, kullanabileceğiniz düzinelerce dil var. Dahili pl / sql ve pl / pgsql hem yetenekli hem de güvenilirdir ve kullanıcıların çok tehlikeli bir şey yapmasını engellemek için bir sanal alan yöntemi kullanır. C ile yazılmış UDF'ler, veritabanının kendisi ile aynı bağlamda çalıştıkları için size en üst düzeyde güç ve performans sunar. Ancak, ateşle oynamak gibi, çünkü küçük hatalar bile arka uçların çarpması veya verilerin bozulmasına neden olacak şekilde büyük sorunlara neden olabilir. Ayrıca, pl / R, pl / ruby, pl / perl ve benzeri gibi custome dilleri, hem veritabanı hem de uygulama katmanlarını aynı dilde yazabilmenizi sağlar. Bu kullanışlı olabilir, çünkü bir UDF yazmak için perl programcı java ya da pl / pgsql etc öğretmek zorunda değilsiniz.

Son olarak, pl / proxy dili var. Bu UDF dili, uygulamanızı ölçeklendirme amacıyla onlarca veya daha fazla arka uç postgresql sunucusunda çalıştırmanıza olanak tanır. Skype'taki iyi insanlar tarafından geliştirilmiştir ve temel olarak fakir bir adamın yatay ölçeklendirme çözümüne izin verir. Yazması da şaşırtıcı derecede kolaydır.

Şimdi, performans konusuna gelince. Bu gri bir alan. Bir kişi için bir uygulama mı yazıyorsunuz? Veya 1000 için? veya 10.000.000 Uygulamanızı oluşturma ve UDF'leri kullanma şekliniz, nasıl ölçeklendirmeye çalıştığınıza LOT'a bağlı olacaktır. Binlerce ve binlerce kullanıcı için yazıyorsanız, yapmak istediğiniz ana şey db üzerindeki yükü mümkün olduğunca azaltmaktır. Veri tabanına taşınan ve veri tabanına geri taşınan veri miktarını azaltan UDF'ler, IO yükünü azaltmaya yardımcı olacaktır. Ancak, CPU yükünü arttırmaya başlarlarsa, o zaman sorun olabilir. Genel olarak konuşmak gerekirse, G / Ç yükünün azaltılması birinci önceliktir ve UDF'lerin CPU'larınızı aşırı yüklememek için verimli olduklarından emin olun

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.