1 puan yazan GN⁺ 2024-02-11 | 1 yorum | WhatsApp'ta paylaş
  • PostgreSQL 16, sorgu planlayıcı/optimizer tarafına 10 iyileştirme ekleyerek DISTINCT, agregasyon, join, pencere fonksiyonları ve partition tablo sorguları için yürütme planı seçeneklerini genişletiyor
  • SELECT DISTINCT, ORDER BY/DISTINCT agregasyonları ve Merge Join sonrası işlemlerde kısmen sıralı girdiler daha etkin kullanılıyor; böylece tam sıralamaya göre daha az bellekle sonuç üretilebiliyor
  • UNION ALL içindeki Memoize, Right Anti Join ve FULL/RIGHT join’ler için paralel hash join desteği, tekrar eden erişimler ile büyük hash tablosu oluşturma maliyetini azaltmaya odaklanıyor
  • Pencere fonksiyonları, gereksiz RANGE işlemeyi ve sona kadar çalıştırılması gereken WindowAgg yükünü azaltıyor; bazı fonksiyonlar ise koşula bağlı olarak erken durdurma yapabiliyor
  • Tüm iyileştirmeler varsayılan olarak etkin geldiğinden, PostgreSQL 16 yükseltmesi öncesi ve sonrasında gerçek iş yüklerinde EXPLAIN çıktıları ile çalışma sürelerini karşılaştırmak faydalı olabilir

PostgreSQL 16 planlayıcı iyileştirmelerinin kapsamı

  • PostgreSQL 16, sorgu planlayıcısına çeşitli iyileştirmeler getirerek birçok SQL sorgusunu önceki PostgreSQL sürümlerine göre daha hızlı çalıştırabiliyor
  • PG16 sürüm notları içinde yer alan planlayıcı iyileştirmelerini daha ayrıntılı biçimde açıklıyor; ayrıca PG15 ve PG16 için EXPLAIN çıktılarının karşılaştırmaları ile yeniden üretilebilir test örnekleri sunuyor
  • Buradaki planlayıcı, diğer ilişkisel veritabanlarında sıkça optimizer olarak adlandırılan bileşendir

Sıralama ve DISTINCT optimizasyonları

  • SELECT DISTINCT içinde Incremental Sort kullanımı

    • Incremental Sort ilk olarak PostgreSQL 13’te eklendi; sonuçlar öncü sütunlara göre zaten sıralıysa yalnızca kalan sütunları sıralayarak maliyeti düşürür
    • PostgreSQL 16 planlayıcısı, SELECT DISTINCT sorgularında da Incremental Sort seçeneğini değerlendiriyor
    • Örneğin a sütununda bir btree indeks varsa ve a, b sırası gerekiyorsa, indeks üzerinden aya göre sıralı sonuç alındıktan sonra a değeri her değiştiğinde yalnızca b sıralanabilir
    • PostgreSQL’in quicksort uygulamasında, tek bir büyük grubu sıralamak yerine birçok küçük grubu sıralamak daha verimli olabilir
    • Örnek sorguda PG15, HashAggregate ve sıralı tarama kullanırken PG16, distinct_test_a_idx indeksini ve Incremental Sort planını seçiyor
    • PG16 çıktısındaki Presorted Key: a, girdinin aya göre zaten sıralı olmasından yararlanıldığını gösteriyor
    • PG15’in hash yaklaşımı yaklaşık 30MB veriyi diske spill ederken, PG16’daki Incremental Sort için azami bellek kullanımı 26KB oldu
    • Çalışma süresi PG15’te 414.226ms iken PG16’da 263.167ms’ye düştü
  • ORDER BY veya DISTINCT içeren agregasyonların optimizasyonu

    • PostgreSQL 15 ve öncesinde, ORDER BY ya da DISTINCT içeren agregat fonksiyonları her zaman sıralamayı Aggregate düğümünün içinde yapıyordu
    • PostgreSQL 16 planlayıcısı, Aggregate düğümüne doğru sıradaki satırları sağlayan yürütme planları oluşturabiliyor; yürütücü de girdi zaten sıralıysa iç sıralamayı atlıyor
    • COUNT(DISTINCT b) örneğinde PG15 ve PG16 her ikisi de GroupAggregate ile Index Only Scan kullanıyor; ancak PG15 çıktısında temp read=4540 written=4560 yer alıyor
    • Bu geçici dosya I/O’su, PG15’teki örtük sıralamanın diske spill ettiğini gösteriyor
    • PG16 çıktısında bu geçici I/O yok ve çalışma süresi PG15’teki 302.693ms’den PG16’da 115.534ms’ye inerek 2 kattan fazla hızlanıyor

Tekrarlayan erişimler ve join planı iyileştirmeleri

  • UNION ALL içinde Memoize kullanımı

    • Memoize plan düğümü ilk kez PostgreSQL 14’te tanıtıldı ve parametreli Nested Loop ile iç girdi arasında bir önbellek katmanı gibi çalışıyor
    • PostgreSQL 16 planlayıcısı, parametreli Nested Loop içinde yer alan iç sorgu UNION ALL olduğunda da Memoize kullanımını değerlendiriyor
    • Örnekte PG15, Append işlemini 1 milyon kez çalıştırırken PG16, Append üzerine Memoize yerleştiriyor
    • PG16’daki Memoize, Hits: 999990, Misses: 10, Memory Usage: 2kB değerlerini kaydediyor
    • Append çalışma sayısı PG15’te 1 milyon iken PG16’da 10’a düşüyor
    • Çalışma süresi PG15’te 1926.151ms’den PG16’da 282.120ms’ye inerek yaklaşık 6 kat hızlanıyor
  • Right Anti Join desteği

    • INNER JOIN içindeki Hash Join için, genelde daha küçük tabloda hash tablosu oluşturmak daha avantajlıdır
    • Küçük hash tabloları daha az oluşturma işi gerektirir, CPU önbelleğine daha uygundur ve CPU’nun ana bellekten veri beklerken stall yaşama olasılığını azaltır
    • PostgreSQL 16 öncesinde Anti Join, NOT EXISTS içinde belirtilen tabloyu her zaman join’in iç tarafına koyuyordu; bu da daha büyük tablo üzerinde hash tablosu oluşturulmasına yol açabiliyordu
    • PostgreSQL 16, Right Anti Join desteğiyle iki tablodan daha küçük olanın hash’lenebilmesini sağlıyor
    • Örnekte PG15, 1 milyon satırlık large tablosunu hash’leyip 6446KB bellek kullanırken PG16, 100 satırlık small tablosunu hash’leyerek yalnızca 12KB kullanıyor
    • Çalışma süresi PG15’te 139.023ms’den PG16’da 77.076ms’ye düşerek neredeyse yarıya iniyor
  • FULL/RIGHT join’ler için paralel hash join

    • PostgreSQL 11, birden çok paralel worker’ın tek bir hash tablosu oluşturmasına katılabildiği Parallel Hash Join özelliğini tanıttı
    • PostgreSQL 16’daki Parallel Hash Join, FULL ve RIGHT join türlerini destekliyor
    • Böylece FULL OUTER JOIN ve Right Join planları da paralel çalıştırılabiliyor
    • FULL JOIN örneğinde PG15 tek bir Hash Full Join kullanırken PG16, Parallel Hash Full Join ile Gather kullanıyor
    • PG16 çıktısında Workers Planned: 1, Workers Launched: 1 görülüyor
    • Çalışma süresi PG15’te 220.677ms’den PG16’da 129.769ms’ye belirgin biçimde düşüyor

Pencere fonksiyonu optimizasyonları

  • Gereksiz RANGE işlemenin atlanması

    • row_number(), rank(), dense_rank(), percent_rank(), cume_dist(), ntile() gibi pencere fonksiyonlarında pencere tanımında ROWS seçeneği yoksa PostgreSQL varsayılan olarak RANGE seçeneğini kullanır
    • RANGE seçeneği, aynı sıralama değerine sahip peer row’ları bulmak için önceki satırları kontrol etmek zorundadır; ORDER BY açısından aynı değere sahip çok sayıda satır varsa maliyet artabilir
    • Bu fonksiyonlarda ROWS ile RANGE belirtilmesi davranışı değiştirmese de, PostgreSQL 16 öncesindeki yürütücü bunu ayırt edemediği için her durumda peer row kontrolü yapmak zorundaydı
    • PostgreSQL 16 planlayıcısı, hangi pencere fonksiyonlarının ROWS/RANGE seçeneklerinden etkilendiğini biliyor ve yürütücünün gereksiz işlemleri atlaması için bilgi aktarıyor
    • row_number() <= 10 örneğinde PG15, indeksten 50.410 satır okuduktan sonra dururken PG16 yalnızca 11 satır okuyor
    • PG16, row_number 11’e ulaştığında <= 10 koşulunu sağlayan başka satır kalmayacağını kullanıyor
    • Çalışma süresi PG15’te 29.775ms’den PG16’da 0.058ms’ye düşerek 500 kattan fazla hızlanıyor
  • Tekdüze artan pencere fonksiyonlarında erken durdurmanın genişletilmesi

    • PostgreSQL 15, WHERE koşulu belirli pencere fonksiyonları için bir kez false olduktan sonra tekrar true olamayacaksa WindowAgg çalışmasını erken durdurabiliyordu
    • PostgreSQL 16, bu optimizasyonu ntile(), cume_dist(), percent_rank() fonksiyonlarını da kapsayacak şekilde genişletiyor
    • PostgreSQL 15’te bu yalnızca row_number(), rank(), dense_rank(), count(), count(*) için geçerliydi
    • percent_rank() <= 0.01 örneğinde PG15 koşulu alt sorgudaki Filter ile işlerken, WindowAgg tüm 50.000 satırı işliyor
    • PG16 ise aynı koşulu Run Condition olarak kullanıp WindowAgg yürütmesini erkenden durduruyor
    • Çalışma süresi PG15’te 84.358ms’den PG16’da 19.454ms’ye düşerek 4 kattan fazla hızlanıyor

Partition tablolar ve bariz DISTINCT işleme

  • Partition tablolarında LEFT JOIN kaldırma

    • PostgreSQL uzun süredir, sorguda gerekmeyen ve satır çoğaltma ihtimali olmayan LEFT JOIN işlemlerini kaldırabiliyordu
    • PostgreSQL 16 öncesinde, partition tablolara yönelik LEFT JOIN kaldırma desteklenmiyordu
    • Bunun nedeni, iç taraftaki satırların dış taraftaki satırları çoğaltmayacağını kanıtlamak için gereken ispatın partition tablolarda bulunmamasıydı
    • PostgreSQL 16 planlayıcısı artık partition tablolar için de LEFT JOIN kaldırma optimizasyonunu uyguluyor
    • Bu optimizasyon özellikle view’larda faydalı olabilir
      • Çünkü view’larda çok sayıda sütun bulunsa da gerçek sorgular her zaman tüm sütunları okumaz
    • Örnekte PG15 planı part_tab ile join içerirken, PG16 planı yalnızca normal_table üzerinde sıralı tarama yapıyor
  • Sonucun tek değere sabitlendiği DISTINCT’in Limit olarak işlenmesi

    • PostgreSQL planlayıcısı, tüm satırların aynı değeri taşıdığını saptayabilirse sonuçtaki tekrarları kaldırmak için ayrı bir plan düğümünü atlayabilir
    • PostgreSQL 16, DISTINCT hedefindeki sütunların tamamı WHERE koşulundaki eşitliklerle sabitlenmişse, sonucun zaten aynı değerlerden oluşacağını kullanarak bunu LIMIT 1 ile işler
    • Örnek sorgu SELECT DISTINCT a,b,c FROM abc WHERE a = 5 AND b = 5 AND c = 5 içinde her DISTINCT sütunu aynı sabit değere sınırlandırılmıştır
    • PG15 tüm sonucu okuyup Unique işleciyle 1 satıra indirirken, PG16 Limit ve sıralı tarama kullanarak yalnızca 1 satır döndürüyor
    • Çalışma süresi PG15’te 30.381ms’den PG16’da 0.025ms’ye düşerek 1200 kattan fazla hızlanıyor

Merge Join sonrasında Incremental Sort kullanımının genişletilmesi

  • PostgreSQL 16 öncesi planlayıcı, Merge Join seçeneğini değerlendirirken join’in sıralama düzenini yalnızca üstteki DISTINCT, GROUP BY, ORDER BY gereksinimleriyle tam olarak eşleştiğinde kullanıyordu
  • Bu kural, Incremental Sortun üst işlemlerde kısmen sıralı girdilerden yararlanabildiği gerçeğini yeterince yansıtmıyordu
  • PostgreSQL 16, Merge Join sıralamasını değerlendirme kuralını “tam eşleşme gerekli” yaklaşımından “en az bir öncü sütun doğru sıralanmış olmalı” yaklaşımına gevşetiyor
  • Bu değişiklikle planlayıcı, Merge Join sonucunu üst işlemlere uyarlamak için Incremental Sortu daha sık kullanabiliyor
    • Incremental Sort, kısmen sıralı girdileri kullanarak küçük partiler halinde sıralama yaptığı için tam sıralamaya göre bellek kullanımını ve karşılaştırma sayısını azaltabiliyor
  • Örnekte PG15, Merge Join sonrasında tam Sort kullanırken PG16 Incremental Sort kullanıyor
    • PG16’daki Incremental Sort için azami bellek kullanımı 26KB oldu
    • Çalışma süresi PG15’te 1010.738ms’den PG16’da 915.589ms’ye sınırlı ölçüde düşerken, sıralama için kullanılan bellek belirgin biçimde azaldı

Uygulama biçimi ve pratik doğrulama

  • PostgreSQL 16’daki 10 planlayıcı iyileştirmesinin tamamı varsayılan olarak etkin geliyor
  • Her optimizasyon ya mümkün olan tüm durumlarda uygulanıyor ya da planlayıcı faydalı gördüğünde seçmeli olarak kullanılıyor
  • Mevcut bir PostgreSQL sürümü kullanıyorsanız, hangi sorguların hızlandığını görmek için gerçek iş yükünüzü PostgreSQL 16 üzerinde çalıştırabilirsiniz
  • Gerçek kullanım geri bildirimleri pgsql-general@postgresql.org e-posta listesi üzerinden paylaşılabilir

1 yorum

 
GN⁺ 2024-02-11
Hacker News yorumları
  • PostgreSQL sorgu planlayıcısının yürütme sırasında sorguyu yeniden planlayabilmesi gerçekten harika olurdu.
    Patolojik derecede yavaş sorgular çoğu zaman planlayıcının veri dağılımı için gereken bilgileri bilmemesi nedeniyle maliyeti yanlış tahmin etmesinden kaynaklanıyor; yürütme süresinin 1 ms yerine 1 saniye olması gibi 1000 kat farklar kolayca ortaya çıkabiliyor.
    Tablo istatistikleri %100 doğru olamayacağına göre, sorgu başladıktan sonra ilerleme hızı beklenenden yavaşsa taranan sayfa sayısı ve eşleşen tuple’lar gibi mevcut ilerleme bilgilerini planlayıcıya geri verip yeni bir plan oluşturmak iyi olurdu.
    Ancak PostgreSQL sonuçları tamamen üretip sonra göndermek yerine akış halinde gönderdiği için, ortada planı değiştirmek için istemciye zaten gönderilmiş sonuçları izlemek gerekir; bu da altyapıda büyük değişiklik demek.
    Üstelik istemci sorgu ortasında yönü tersine çevirip önceki sonuçları ters sırayla yeniden isteyebildiğinden karmaşıklık daha da artıyor.

    • Blog yazarı ve PostgreSQL committer’ı olarak, bu özelliğin olmasını ben de isterdim. Ancak istemciye tuple gönderme meselesi yukarıda anlatılandan daha çetrefilli.
      Çünkü yeni planın aynı tuple’ları döndüreceğinin garantisi bile yok. Örneğin SELECT * FROM table LIMIT 10 gibi ORDER BY olmayan bir sorguda hangi tuple’ların geleceği deterministik değildir.
      Bunun yerine X adet tuple’ı bir kuyruğa alıp, kuyruk dolduğunda göndermeye başlamak daha kolay olabilir. Kuyruk dolduktan sonra yeniden planlama için çok geç olduğu kabul edilip mevcut plana sabitlenilir.
      Kullanıcı X’i ayarlayarak daha fazla bellek ve ilk tuple gecikmesini göze alabilir; buna karşılık planı değiştirebilmek için daha uzun bir zaman penceresi kazanır.
    • Başka bir bakış açısı da uzun planlama yapılmasına izin verilen sorgulara sahip olmak olabilir. En iyi planı seçmek için 1 saniye ya da birkaç saniye harcanmasına izin verilir; bu sırada daha fazla istatistik toplanabilir veya sorgu kısa süreliğine çalıştırılıp denenebilir.
    • İstemcinin sorgu ortasında yönü tersine çevirip önceki sonuçları ters sırayla geri alma özelliğinin nerede işe yaradığını merak ediyorum.
    • Sorgu sıralama düzenini tamamen belirlemiyorsa, sorgu planının sonuç sırasını etkileyip etkileyemeyeceğini merak ediyorum. Eğer etkiliyorsa önerilen yöntem neredeyse imkânsız olabilir.
      Yeni sorgu yalnızca ilk N sonucu atlayamaz; daha önce gönderilmiş her satırı bir sözlükle karşılaştırmak zorunda kalır.
    • Bu makale ve atıf yaptığı makaleler ilginizi çekebilir: https://arxiv.org/pdf/1902.08291
  • Sorgu görselleştirme için şu aracı kullanıyorum: https://explain.dalibo.com/
    https://www.pgexplain.dev/ de var; eskiden çıktısı daha kötüydü ama şimdi ikisi de benzer görünüyor.

    • Araç harika ve kullanıyorum, ama planda kötü görünen kısımlara bakıp yaklaşımımı nasıl düzeltmem gerektiğini bilecek kadar derinlemesine anlamıyorum.
    • Profiline bakınca fintech CTO’su olduğunu görüyorum; o aracın “önemli veya hassas bilgileri göndermemeniz önerilir” uyarısını nasıl ele aldığını merak ediyorum.
      Böyle durumlarda yardımcı olacak bir yürütme planı arındırma aracı var mı merak ediyorum.
  • Sorgu planlayıcısındaki iyileştirmeler her zaman memnuniyet verici ve veritabanlarında çok önemli bir parça. Elbette genelde en çok, istediğim gibi çalışmadığında göze çarpıyor.
    Kişisel olarak epey sinir bozucu bulduğum bir konu, güncel PostgreSQL’deki JIT. Ne zaman kullanılacağını belirleyen heuristikler hiç sağlam görünmüyor.
    Tipik bir ORM’in ürettiği sorguda gördüm: sorgunun kendisi basit ama join’lerle çok sayıda tabloyu içeri çekiyor. JIT olmadan birkaç milisaniyede bitiyor; JIT ise 1–1,5 saniye ek süre harcayarak küçük veride bile sorguyu aşırı yavaşlatıyor.
    Artık JIT’i kapatmanın yeterli olduğunu biliyorum, ama neden yavaş olduğunu hâlâ çözemeyen kullanıcılar için PostgreSQL hakkındaki izlenimi ciddi biçimde bozabilir. PostgreSQL’i seviyorum, ama JIT’i varsayılan olarak açık tutmak fazla riskli görünüyor.

    • Blog yazarı ve PostgreSQL committer’ı olarak, JIT kullanılıp kullanılmayacağına karar veren kodun iyileştirilmesi gerektiğine kesinlikle katılıyorum.
      PG16’da yalnızca planın tahmini toplam maliyetine bakılıyor; derlenmesi gereken ifade sayısı hesaba katılmıyor.
      Birkaç ifadeyi derlemek hızlıdır, ama yüzlerce partition’ı olan partition’lı bir tablo sorgulanır ve bu partition’ların hepsi plana girerse JIT derleyicisinin yapacak çok işi olur.
      Bir meslektaşımla birlikte bunu iyileştiren kodumuz var, ancak şu an itibarıyla PG17’ye girip girmeyeceği kesin değil.
    • JIT’te garip hissettiren bir başka şey de üretilen kodun önbelleğe alınmaması. Sorgu yürütmede çoğu zaman en pahalı kısım bu oluyor; neden önbelleğe alınmadığını bilmiyorum.
      PostgreSQL posta listelerinde JIT ile ilgili tartışmalara baksam da ikna edici bir neden bulamadım.
      OLTP iş yüklerinde JIT’i kapatmak doğru tercih.
    • JIT’in pratikte başarısızlığa yakın olduğunu düşünüyorum. Niyet iyiydi ama LLVM bunun için uygun araç değil. Global olarak kapattım.
      ORM kullanmadığım için mesele yalnızca tuhaf sorgu kalıplarından da ibaret değil.
      Buna karşılık sorgu paralelleştirme gerçekten faydalı olabiliyor ve en önemlisi, yalnızca nadiren zarar veriyor.
    • Yakın zamanda production’da JIT ile ilgili tuhaf bir bug’la karşılaştım.
      apt ile birkaç paketi güncelledikten sonra her 5 dakikada bir çalışan büyük bir sorgu aniden başarısız olmaya başladı. Daha doğrusu PostgreSQL, sorgu yürütmenin ortasında hiçbir log bırakmadan bağlantıyı sessizce koparıyordu.
      Elle EXPLAIN çalıştırarak kontrol ettiğimde, yalnızca JIT kullanan sorgu varyantının bozulduğunu; kullanmayan tarafın sorunsuz olduğunu gördüm. JIT’i kapatınca her şey normale döndü.
    • Prepared statement kullanarak derlemeyi yalnızca bir kez yapıp, derleme sonucunu o sorgunun her çalıştırılmasında yeniden kullanmayı denediniz mi merak ediyorum.
  • Bu değişikliklerin gerçek sorgularda ne kadar sık etkili olduğunu merak ediyorum. Özellikle “mümkün olduğunda DISTINCT uygulamasında Unique yerine Limit kullanma” değişikliği, yalnızca çok aptalca sorgulara uygulanacakmış gibi geliyor
    PostgreSQL geliştiricilerinin bunu değerlendirebilecek bir bilgi kaynağı olup olmadığını merak ediyorum

    • Oldukça sık etkisi olacak gibi. DISTINCT, deneyimi az geliştiricilerin kötü bir sorguyu düzeltmeye çalışırken sıkça eklediği bir şey; genellikle performans iyileştirmeye başlarken yapılan ilk iş de onu gereksiz kılacak şekilde sorguyu yeniden yazmaktır
      DISTINCT iyileştirmesi kötü sorgulara karşı sistemi daha dayanıklı hâle getiriyorsa bundan kazanılacak çok şey var. Tüm sorunları çözemez ama her türlü iyileştirme memnuniyetle karşılanır
    • Blog yazarı ve ilgili özelliğin yazarı olarak, bu konu gerçekten pgsql-hackers posta listesinde gündeme geldi
      Sık uygulanma olasılığının düşük olduğuna katılıyorum; ama güzel yanı, uygulanabilir olup olmadığını tespit etmenin bir işaretçinin NULL olup olmadığını kontrol etmek kadar basit olmasıydı
      Tespit çok basit ve çoğu durumda uygulanmayacak; ancak uygulanabildiği durumlarda ciddi bir performans artışı sağlayabilir
    • Sorun şu ki ORM’lerin çok aptalca sorgular üretme alışkanlığı var ve geliştiriciler SQL’i doğrudan yazıp düzeltmeyi nedense saf olmayan bir şeymiş gibi reddediyor
      Çok yaygın bir sorun olmayabilir ama ara sıra ortaya çıksa şaşırmam
    • Eski iş yerimde, miras nedenlerle kullanıcı tablosunda yinelenen e-posta adreslerine izin veriliyordu; ancak yeni tekrarlar eklemek istemediğimiz için yeni kullanıcı oluşturmadan önce select distinct email from users where email = ? sorgusunu çalıştırıyorduk
      Aynı e-postaya sahip satırların 100’ü geçtiğini sanmıyorum. Çoğu silinse sorun olmayacak test kullanıcılarıydı ama konu biraz dağıldı
  • PostgreSQL’de uygulama testleri için bir strict mode olsa iyi olurdu. Yalnızca sorgunun kendisine bakıp, istatistiklerden bağımsız olarak bir indeks varsa sorgu asimptotik olarak iyileşiyorsa ama o indeks yoksa hata döndüren bir mod
    Uygulama yükseltmeleri için ilgili indeksi oluşturan bir CREATE INDICES FOR komutu da olsa iyi olurdu; etkileşimli ve geliştirme amaçlı kullanım için otomatik indeks oluşturma modu da isterdim
    Genel olarak sistem, asimptotik olarak optimal olmayan yürütmelerin asla gerçekleşmemesini sağlayacak şekilde tasarlanmalı

  • Neden hint uygulamadıklarını bilmiyorum

    • pg_hint_plan eklentisi var. Hint’lerin riski, yazıldıkları anda doğru olsalar bile tablo boyutu ya da veri dağılımındaki çarpıklık değişince işleri daha da kötüleştirebilmeleri
      Daha önce hint tartışmalarını gördüğümde, plancıyı çok sıkı bağlamadan temel veri değişimlerine uyum sağlayabilecek bir yöntemse genel bir itiraz olmadığını hatırlıyorum
      Örneğin belirli bir koşulun 10 satırla eşleştiğini belirtmek yerine, iki sütun arasında korelasyon olduğunu söylemek gibi
    • İlgili tartışma: Why PostgreSQL doesn't have query hints
      https://news.ycombinator.com/item?id=2179433 (60 yorum, 2011)
      PostgreSQL vikisindeki resmi tutum https://wiki.postgresql.org/wiki/OptimizerHintsDiscussion adresinde yer alıyor
      Tutumları, “diğer veritabanlarında yaygın olarak uygulanan tam biçimiyle hint’lerle ilgilenmiyoruz” yönünde
      Mevcut hint sistemlerinin sorunları arasında uygulama kodunun bakımını zorlaştırması, yükseltmeleri engellemesi, kötü DBA alışkanlıklarını teşvik etmesi ve veri boyutu büyümesine uygun olmaması sayılıyor
      Bu tutumu suçlamak istemem; ama PostgreSQL aptalca bir plan seçtiğinde ve onu makul bir seçim yapmaya ikna edemediğinizde insan sinirleniyor
  • Orta ölçekli şirketlere bakan Microsoft DBA olan bir arkadaşım, PostgreSQL ile ciddi iş yapılamayacağını söylemişti. Hatta PostgreSQL'de sorgu planlayıcı bile olmadığını öğrenince şoke olduğunu söyledi
    Alayı bir kenara bırakırsak, MSSQL'in PostgreSQL'in uygun olmadığı ölçekleri kaldırabildiği yönündeki daha büyük iddiada bir doğruluk payı olup olmadığını merak ediyorum. İçgüdüsel olarak saçma geliyor ama DBA falan değilim

    • Bu açıdan bir yanı var. İhtiyacınız olan neredeyse her şeyi yeterince iyi halleden bir veritabanıysa MSSQL ve Oracle'ın bunu yapabilme ihtimali yüksek
      Bunlar sorun çözülene kadar para ve donanım, yani daha fazla para basarak ilerleme yöntemiyle çözülmüş şeyler. Elbette akıllıca teknolojiler de var, ama temelde uzun süre boyunca çok daha fazla mühendislik yatırımı yapılmış
      PostgreSQL'in makul biçimde yapabileceğinden daha büyük ölçekte yatay ölçeklenebilirler
      Yine de PostgreSQL de arayı kapatıyor; MySQL/MariaDB'nin de bu konuda hikâyesinin her zaman fena olmadığı söylenebilir. Yatay ölçekleme seçenekleri sürekli daha iyi hale geliyor
      Artık az sayıda makineyle çok terabaytlık PostgreSQL kümeleri çalıştırıp yüksek trafiği karşılamak ve “büyük veriyi” daha uzmanlaşmış veritabanlarına koymak da kolaylaştı. Her şeyi MSSQL/Oracle'a tıkıştırdığımız eski yaklaşım biraz modası geçmiş olabilir
    • MSSQL ile çok geliştirme yaptım; PostgreSQL'de biraz şaşırtıcı bazı eksik özellikler var
      Arkadaşının kastettiği şey, PostgreSQL'in sorgu planlarını önbelleğe alma veya sabitleme yöntemi olmaması olabilir. PostgreSQL, elle hazırlanmış ifadeler kullanmadığınız sürece her ifadeyi yeniden planlar; o da yalnızca bağlantı bazında çalışır
      MSSQL uzun zamandır planları önbelleğe alıp yeniden kullandığı için planlayıcı plan oluşturmaya daha fazla zaman ayırabilir. Ayrıca hint'leri vardır ve planı sabitleyebilirsiniz
      PostgreSQL'in gerçekten hint'lere ihtiyacı var. İyileştirici harika olsa bile bazen ben daha iyi bilirim ve beni dinlemesini isterim
      Ayrıca PostgreSQL'de gerçek bir clustered index yok; tüm tablolar heap'tir. MSSQL'de çoğu kişi bunu sık kullanır; genelde birincil anahtarı clustered index yaparsınız, böylece tablonun kendisi indeks olur ve anahtar aramalarında dolaylı başvuru olmaz
      İlginç biçimde SQLite'ta durum tersidir: tablolar, siz oluştursanız da oluşturmasanız da her zaman clustered index'e sahiptir; MSSQL ise heap ile indeks örgütlü tablo arasında seçim yapmanıza izin verir
    • PostgreSQL'de sorgu planlayıcı var. Bu yazının tamamı onun iyileştirilmesiyle ilgili. Yani ya iletişimde bir yanlışlık olmuş ya da arkadaşın PostgreSQL'i hiç bilmiyor gibi
      Çok büyük PostgreSQL veritabanlarının da iyi çalıştığı örnekler var; dolayısıyla PostgreSQL kesinlikle ölçeklenebilir
      Ancak SQL Server'da PostgreSQL'de olmayan özellikler de var ve bunlar önemliyse belirli kullanım durumlarına daha uygun olabilir. Sonuçta farklı güçlü ve zayıf yönleri olan farklı veritabanları
    • Hem OLTP hem veri ambarı tarafında ikisini de kullandım; ikisi de gayet iyi
      Başta, SQL Server gerektiren tedarikçi uygulamaları olmasaydı şirkete PostgreSQL'e geçiş önereceğimi yazacaktım
      Ama sonra Microsoft'un birlikte verdiği reporting services, integration services, işler, AD entegrasyonu, service broker gibi şeylerin yerine ne kadar çok şey koymak gerekeceğini fark ettim. notify/listen içinde mesaj tipi yok
      analysis services'i artık kullanmıyoruz ama eskiden kullandığımızda onu da değiştirmek zor olurdu
      İnsanları elde tutan şeyler bunlar. Tüm bunların yerine yenilerini koymanın ne kadar süreceğine dair fikrim bile yok; zaten sahip olduğumuz şeyleri değiştirmek için 1 yıl harcamak yatırım getirisi açısından iyi değil
    • AWS'nin Aurora'sı bunu oldukça iyi hallediyor gibi ve PostgreSQL ile MySQL için drop-in alternatif olmayı hedefliyor
  • Bunun neden postgresql.org yerine citusdata üzerinde yayımlandığını merak ediyorum. Ücretli özelliklere özel mi, yoksa açık kaynak bir ekleme mi bilmiyorum

    • Çünkü yazarı Citus Data'da çalışıyor ve söz konusu optimizasyonların bir kısmını da bizzat o yazdı
  • IS NOT DISTINCT FROM sorgularını hızlandırmak için indeks kullanabilmemiz ne zaman mümkün olacak acaba ;)