· kaynak dev.to (home feed)
PostgreSQL 18 benchmarkı: UUIDv7 insert işlemleri UUIDv4'ten neredeyse 10 kat daha hızlı
Yapılan bir dev.to benchmarkı, ölçek büyüdükçe PostgreSQL 18'deki UUIDv7 primary key'lerin UUIDv4'ten neredeyse 10 kat daha hızlı insert edildiğini, B-tree index'lerin ise her test edilen boyutta yaklaşık çeyrek daha küçük kaldığını ortaya koyuyor.

Benchmark
dev.to'da yayımlanan uygulamalı bir karşılaştırma, PostgreSQL 18'in yerleşik UUIDv7 desteğinin gerçekte ne kadar değerli olduğunu sayısallaştırmayı hedefledi. Yazar, şema tasarımı için önemli iki şeyi ölçtü: toplu insert işlemlerinin ne kadar sürdüğünü ve ortaya çıkan primary key index'inin ne kadar disk alanı tükettiğini.
Test, tek sütunu PRIMARY KEY olarak işaretlenmiş bir UUID olan tablolara 1, 10 ve 100 milyon satır yükledi; bu, PostgreSQL'in varsayılan olarak bu sütunda benzersiz bir B-tree index'i tutması anlamına geliyor. Karşılaşan iki taraf, sentetik anahtarların köklü varsayılanı olan UUIDv4 ile, PostgreSQL 18'in artık uuidv7() aracılığıyla yerleşik olarak üretebildiği UUIDv7'ydi.
Gönderiye göre sonuç şu: küçük hacimlerde iki varyant neredeyse ayırt edilemez, ancak satır sayısı arttıkça fark açılıyor ve UUIDv7 insert işlemleri UUIDv4'ten neredeyse on kat daha hızlı tamamlanıyor. Index boyutu her ikisinde de doğrusal büyüyor, ama v7 index'i test edilen her ölçekte yaklaşık çeyrek daha küçük kalıyor.
Yazar bir milyar satırı da grafiklemek istedi, ancak UUIDv4 koşusunun tek başına makinesinde bir saatten fazla süreceği görülünce bu fikirden vazgeçti.
Rastgele anahtarlar insert'leri neden yavaşlatır
Mekanizma, iki biçimin nasıl inşa edildiğinden geliyor. Gönderide atıf yapılan RFC 9562'ye göre UUIDv7, baştaki 48 bitini milisaniye çözünürlüklü bir Unix timestamp'e ayırıyor; dolayısıyla sonradan üretilen tanımlayıcılar öncekilerden sonra sıralanıyor. UUIDv4 ise tamamen rastgeledir.
Bu fark doğrudan B-tree davranışına yansıyor. Yeni bir UUIDv7 her zaman index'teki her şeyden sonra sıralanır; böylece PostgreSQL yalnızca en sağdaki yaprağı bulmak zorundadır — neredeyse kesin olarak cache'te sıcak olan bir sayfa. Yeni bir UUIDv4 ise anahtar uzayında rastgele bir yere düşer ve motoru, doğru yaprağı bulmak için tamamen alakasız sayfaları RAM'e çekmeye zorlar. Bu ek yük tablo büyüdükçe katlanır; insert sürelerinin ölçekte ayrışmasının nedeni de budur. Gönderi yavaşlamayı tam olarak bu örüntüye bağlıyor; index boyutu farkını ayrıca açıklamıyor, oysa dağınık rastgele anahtarlar B-tree sayfalarını genellikle sıralı eklemelere göre daha az yoğun doldurur.
Test nasıl yürütüldü
Kurulum bilinçli olarak basit ve tekrarlanabilir. Yazar, Docker'da postgres:18.6 imajını, her biri tek bir UUID primary key sütunu içeren test_v4 ve test_v7 adlı iki yalın tabloyu barındıran bir init script'i ile çalıştırdı. Satırlar sunucu tarafında insert into test_v7(id) select uuidv7() from generate_series(1,1_000_000) gibi ifadelerle üretildi; geçen süre psql'in \timing on özelliğiyle kaydedildi. Index boyutları pg_size_pretty(pg_relation_size(...)) ile okundu ve koşular arasında tablolar truncate edildi ve vacuumlandı. Benchmark kodunun tamamı yazarın GitHub'ında.
Dikkate değer uyarılar
Yazar sayıların sınırları konusunda açık sözlü. Kesin süreler başka donanımlarda farklılık gösterecektir ve benchmark her veri setini tek büyük bir ifadede insert etti — yani uygulama verimi, ağ gidiş-dönüşleri ve çok sayıda küçük transaction'ın üreteceği ek WAL trafiği kapsam dışıdır. Gerçek dünya iş yükleri, göreli eğilim korunsa bile farklı mutlak rakamlar beklemelidir.
Gönderi, ham hızın ötesinde bir başka v7 avantajına daha dikkat çekiyor: aynı anda civarında üretilen tanımlayıcılar aynı index sayfasında saklanmaya meyilli kalıyor ve bu, ilgili satır gruplarını çeken sorgulara yardımcı oluyor. Tartışmadığı bir takas ise şu: bir v7 değeri oluşturulma zamanını gömdüğü için, açığa çıkan tanımlayıcılar bir satırın kabaca ne zaman yazıldığını ele veriyor — herkese açık URL'lerde veya API'lerde kullanmadan önce bunu tartmakta fayda var.
Neden önemli
Primary key biçimi erken verilen, yıllarca birlikte yaşlanan ve geri döndürülmesi acı veren bir karardır — üretimdeki bir sistemdeki her anahtarı pek kolay kolay yeniden yazamazsınız. PostgreSQL 18 ve sonrası üzerindeki yeni şemalar için bu benchmark, yüksek hacimli tablolarda varsayılan olarak UUIDv7'yi seçmek için somut bir gerekçe sunuyor: veri alımı daha hızlı işliyor, index'ler küçük kalıyor, buffer-cache çalkantısı azalıyor ve kabaca satırların zaman sıralamasını bedavaya edinirsiniz. UUIDv4'e şimdiden bağlı olan ekipler bunu bir göç zorunluluğu olarak okumamalı, çünkü benchmark'ın koşulları tipik OLTP trafiğinden farklıdır; ama çözüm bir CREATE TABLE ifadesinde tek kelimelik bir değişiklikken, on katlık insert farkını ve %25'lik index tasarrufunu görmezden gelmek zor.
- #postgresql
- #databases
- #performance
- #uuid
- #benchmark