2012-10-17 20 views
8

10m satırlı büyük bir tablom var. Ve her satır için biraz istatistik değeri almam gerekiyor. Bu değeri üreten işlevim var, örneğin GetStatistic(uuid). Bu fonksiyonlar çok yavaş çalışır ve sonuç değeri çoğu zaman değişir, bu nedenle benim tablosundaki sütun Statistic oluşturduk ve günde bir kez böyle sorguyu çalıştırın:Postgresql. Güncelleme sorgusunu paralellde çalıştırabilir miyim?

UPDATE MyTable SET Statistic = GetStatistic(ID); 

Ve seçme sorguları i GetStatistic uğramadan sütun Statistic kullanmak fonksiyonlar.

Sorun benim yapım sunucusu böylece neredeyse tüm DB RAM belleğe alınabilir 64 CPU ve bellek yeri vardır, ancak bu sorgu kullanımı yalnızca bir işlemci ve yürütmek için 2 veya 3 saat ihtiyaç vardır. UPDATE sorgusu her yürütülmesi sırasında sabittir

GetStatistic işlev kullanımı tablo. Tüm uyumlu CPU'ları kullanarak farklı satırlar için paralel olarak GetStatistic'i hesaplamak için postgre almak için sorguyu değiştirebilir miyim?

+0

Neden bir işlev kullanın, düz SQL tarafından gerçekleştirilemeyen bir şey var mı? İşlev sadece geçerli satırdan değerlere mi ihtiyaç duyar, yoksa diğer veri kaynaklarını da içerir mi (: = tablo)? Btw: bize işlevi gösterir. – wildplasser

+0

Bu sorgunun planını kontrol edin, bu işlevin 10M kere çağrıldığını göreceksiniz. Belki de onu salt SQL'e yazmak daha iyi olurdu ve daha hızlı olabilirdi. –

cevap

9

Postgresql tek bir iplik ile bir süreçtir tek arka uç her bir sorgu çalıştırır. Bir sorgu için birden fazla CPU kullanamaz. Aynı zamanda I/O eşzamanlılığının tek bir sorguda elde edebileceği, sadece bitmap dizin taramaları için eşzamanlı I/O yapan ve eşzamanlı I/O için işletim sistemi ve disk sistemine dayanan bir şekilde sınırlı.

Pg, birçok küçük sorgunun eşzamanlı yüklerinde iyidir ve sisteminizi bu şekilde doyurmak çok kolaydır, bir ya da iki büyük sorgu için sistem kaynaklarını en iyi şekilde kullanmak iyi değildir. parçalar halinde yukarı işi bölünmüş ve işçilere elden teslim edilir Ne yapabilirsiniz

. Tüm kullanılabilir CPU kullanan, postgre aynı anda farklı satırlar için paralel yılında GetStatistic hesaplamak almak için

i değiştirebilir sorgusu: Sen bu ima ettik?

DBlink, PL/Proxy, pgbouncer ve işin bu tür yardımcı olmak üzere tasarlanmıştır PgPool-II gibi çeşitli araçlar vardır. Alternatif olarak, her biri veritabanına bağlanan ve birbiriyle örtüşmeyen ID aralıklarına sahip UPDATE ... WHERE id BETWEEN ? AND ? ifadeleri yapan 8 işçiyi başlatabilirsiniz. Daha sofistike bir seçenek, bir kuyruk kontrolörünün, çalışanlara yaklaşık 1000 ID değerine sahip menzilleri vermesidir. Bu aralıktaki UPDATE o zaman yeni bir tane isteyin. 64 CPU'lar 64 eşzamanlı işçiler idealdir anlamına gelmez

Not. Disk G/Ç'niz, yazım söz konusu olduğunda da bir faktördür. Eğer bir commit_delay kullanmak üzere UPDATE işlemleri ayarlamak ve (bu veriler için iş gereksinimleri için güvenli değilse) synchronous_commit = 'off' sonra senkronize edilmez yük önemli ölçüde azaltılmalıdır eğer I/O maliyeti biraz yardımcı olabilir. Yine de, 'muhtemelen en iyi iş çıkışı 64 eş zamanlı çalışanın çok altında gerçekleşecek.

Büyük olasılıkla, GetStatistic işlevinizin, büyük olasılıkla bir döngü ağır yordamsal PL/pgSQL işlevinin şu anda ne olduğundan ziyade, bir SQL işlevine veya görünümüne dönüştürerek çok daha hızlı yapılabilmesi olasıdır. Bu işlevi gösterdiğinizde yardımcı olabilir.

İlgili konular