Sorumun 2 kısmı var.
- PostgreSQL'de bir veritabanının başlangıç boyutunu belirtmenin bir yolu var mı?
- Eğer yoksa, veritabanı zaman içinde büyüdüğünde parçalanma ile nasıl başa çıkıyorsunuz?
Son zamanlarda MSSQL'den Postgres'e geçtim ve bir veritabanı oluştururken MSSQL dünyasında yaptığımız şeylerden biri, veritabanı ve işlem günlüğünün başlangıç boyutunu belirtmekti. Bu, özellikle veritabanının "normal" boyutu önceden biliniyorsa, parçalanmayı ve performansı arttırdı.
Boyut büyüdükçe veritabanımın performansı düşüyor. Örneğin, yüklediğim iş yükü normalde 10 dakika sürer. Veritabanı büyüdükçe, bu süre artar. Bir VAKUM, VAKUM TAM ve VAKUM TAM ANALİZ yapmak sorunu çözmez. Performans sorununu çözen, veritabanını durdurmak, sürücüyü parçalara ayırmak ve ardından VAKUM FULL ANALYZE yapmak, testimin performansını orijinal 10 dakikaya geri götürmektir. Bu beni parçalanmanın acı çekmeme neden olduğundan şüpheleniyor.
Postgres'te tablo alanı / veritabanı alanı ayırmak için herhangi bir referans bulamadım. Ya yanlış terminolojiyi kullanıyorum ve böylece hiçbir şey bulamıyorum ya da Postgres'te dosya sistemi parçalanmasını hafifletmenin farklı bir yolu var.
İşaretçi var mı?
Çözüm
Verilen cevaplar şüphelendiğim şeyi doğrulamamda yardımcı oldu. PostgreSQL, veritabanını birden fazla dosyada saklar ve bu, veritabanının parçalanma endişesi olmadan büyümesine izin verir. Varsayılan davranış, bu dosyaları, nadiren değişen tablolar için iyi ancak sık sık güncellenen tablolar için kötü olan tablo verileriyle ağzına kadar paketlemektir.
PostgreSQL, MVCC'yi tablo verilerine eşzamanlı erişim sağlamak için kullanır . Bu şema altında, her güncelleme güncellenen satırın yeni bir sürümünü oluşturur (bu zaman damgası veya sürüm numarası ile olabilir, kim bilir?). Eski veriler hemen silinmez, ancak silinmek üzere işaretlenir. Gerçek silme, bir VAKUM işlemi gerçekleştirildiğinde gerçekleşir.
Bunun doldurma faktörü ile ilişkisi nedir? 100'ün varsayılan tablo doldurma faktörü, tablo sayfalarını tam olarak paketler; bu da tablo sayfasında güncellenmiş satırları tutacak boşluk olmadığı anlamına gelir; yani, güncellenen satırlar orijinal satırdan farklı bir tablo sayfasına yerleştirilir. Deneyimlerimin gösterdiği gibi bu performans için kötü. Özet tablolarım çok sık güncellendiği için (1500 satıra / saniyeye kadar), 20'lik bir doldurma faktörü ayarlamayı seçtim, yani tablonun% 20'si eklenen satır verileri için ve% 80'i güncelleme verileri için olacaktır. Bu aşırı gibi görünse de, güncellenmiş satırlar için ayrılan geniş alan, güncellenen satırların orijinalle aynı sayfada kaldığı ve otomatik vakum daemonunun eski satırları kaldırmak için çalıştığı zaman dolu bir tablo sayfası olmadığı anlamına gelir.
Veritabanımı "düzeltmek" için aşağıdakileri yaptım.
- Özet tablolarımın doldurma faktörünü 20 olarak ayarlayın. Oluşturma sırasında CREATE TABLE'a bir parametre ileterek veya bundan sonra ALTER TABLE ile yapabilirsiniz. Aşağıdaki plpgsql komutunu verdim:
ALTER TABLE "my_summary_table" SET (fillfactor = 20);
- Bu tablo dosyasının tamamen yeni bir sürümünü yazdığı ve dolayısıyla ima yoluyla yeni doldurma faktörü ile yeni bir tablo dosyası yazdığı için bir VAKUM TAM yayınladı .
Testlerimi yeniden çalıştırdığımda, veritabanı milyonlarca satırla ihtiyaç duyduğum kadar büyük olduğunda bile performans düşüşü görmüyorum.
TL; DR - Dosya parçalanması nedeni değil, tablo alanı parçalanmasıydı. Bu, tablonun dolgu faktörüne özel kullanım durumunuza uyacak şekilde ayarlanarak hafifletilir.