PostgreSQL: Verileri belleğe zorla


32

PostgreSQL'i belirli bir tabloyu belleğe yüklemeye zorlamak ya da en azından sistem tarafından önbelleğe alınmasını sağlamak için diskten okumak için sistematik bir yöntem var mı?

Yanıtlar:


25

E- posta listesi konularından birine girebilirsiniz , Tom Lane tarafından cevaplanmıştır (çekirdek dev):

[..] Ama benim görüşüme göre, bir LRU önbellekleme algoritmasından daha akıllı olduğunu düşünen insanlar genellikle yanılıyor. Eğer masa tamamen kullanılmışsa, bellekte kalır. Bir LRU algoritmasına göre bellekte kalmak için yeterince kullanılmazsa, belki de bellek alanı gerçekten başka bir şeye harcanmalıdır. [..]

Ayrıca bir SO sorusuna da itirazda bulunabilirsiniz : https://stackoverflow.com/questions/486154/postgresql-temporary-tables ve belki daha uygun https://stackoverflow.com/questions/407006/need-to-load-the -Bütün-postgresql veritabanı içine--ram


1
+1 Aynı fikir diğer RDBMS'ler için de geçerlidir.
gbn

25
Evet ve hayır. Bazı Oracle tablolarını bellekte kilitledik çünkü sık sık kullanılamayabileceklerini biliyoruz, ancak kullanılmadıkları durumlarda gecikme bir katil olacaktır. Bir DB her zaman DBA final deyimini vermelidir (başka bir örnek, sorgu iyileştiriciyi ima etmektir).
Gaius,

35

PostGres 9.4 sonunda verileri işletim sistemi veya veritabanı tampon önbelleği ile olan ilişkilerden önceden yüklemek için bir uzantı ekledi (seçiminize göre):

pg_prewarm

Bu, tam çalışma performansına daha hızlı bir şekilde ulaşılmasını sağlar.

Veritabanında bir kez çalıştırın ( burada ayrıntılı talimatlar ):

CREATE EXTENSION pg_prewarm;

Sonra verilen herhangi bir ilişkiyi önceden yüklemek basittir. Temel örnek:

SELECT pg_prewarm('my_tbl');

my_tblArama yolunda adı verilen ilk tabloyu bulur ve Postgres tampon önbelleğine yükler.

Veya:

SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');

prefetchBu desteklenirse, işletim sistemine zaman uyumsuz ön satın alma istekleri yayınlar veya aksi takdirde bir hata atar. read istenen blok aralığını okur; aksine prefetch, bu senkronize ve tüm platformlarda ve yapılarda desteklenir, ancak daha yavaş olabilir. bufferistenen blok aralığını veritabanı tampon önbelleğine okur.

Varsayılan değer buffer, en büyük etkiye sahip olan (yüksek maliyet, en iyi etki).

Daha fazla bilgi için kullanım kılavuzunu okuyun , alıntılar oradan.
Depesz de bunun hakkında blog yazdı .


4

Genel durumda, yeterli RAM’iniz varsa, genellikle RAM’de düzenli olarak kullandığınız şeyleri iyi bir şekilde yapmak için veritabanı servisine güvenebilirsiniz. Bazı sistemler, tablonun her zaman RAM'de tutulması gerektiğine dair ipucu verir (bu, sık kullanılmayan ufacık tablolar için kullanışlıdır, ancak kullanıldığı zaman, mümkün olduğunca çabuk cevap vermeleri önemlidir), ancak pgsql'de böyle bir tablo ipucu varsa uygulamanızı genel olarak yavaşlatabilmeniz için başka bir şeyi önbelleğe almak için kullanabileceğiniz hafıza miktarını azalttığınız için bunları kullanırken çok dikkatli olmanız gerekir.

Veritabanının sayfa önbelleğini başlangıçta başlatmak istiyorsanız (örneğin, yeniden başlatma veya DB'nin önbelleğe alınan her şeyi unutmasına neden olan başka bir bakım işleminden sonra) sonra aşağıdakileri yapan bir komut dosyası yazın:

SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>

(bu son adım, her bir dizin veya kurs için tekrarlandı ve SİPARİŞ BY deyimindeki alanların doğru sırada olmasına dikkat edin)

Yukarıdakileri çalıştırdıktan sonra her veri ve indeks sayfasının okunması gerekirdi ve bu nedenle RAM sayfası önbelleğinde olacaktır (en azından şimdilik). Yeniden başlatıldıktan sonra çalıştırılan uygulama veritabanlarımız için böyle komut dosyalarımız var, böylece daha sonra sisteme giriş yapan ilk kullanıcılar daha yavaş yanıt verebilir. Db tanım tablolarını (yerine sys.objects/ sys.indexes/ / sys.columnsMSSQL'de olduğu gibi) taramak yerine, bu tür herhangi bir komut dosyasını elden yazarken daha iyi olursanız, daha uzun sürecek her şeyi taramak yerine, en sık kullanılan dizinleri seçici olarak tarayabilirsiniz .


3
Bu işe yaramaz, en azından PostgreSQL'de. Tüm tampon önbelleğinin kullanılmasını önlemek için sıralı taramalar için paylaşılan tamponlardan küçük (256KB) bir halka tamponu tahsis edilir. Ayrıntılar için github.com/postgres/postgres/blob/master/src/backend/storage/… adresine bakın. Bunu, büyük bir tablodan bir SELECT * yaparak, sonra pg_buffercache tablosuna bakarak (pg_buffercache uzantısından) doğrulayabilirsiniz.
hbn

- @hbn merhaba ama iplik tasarrufu bu bu adam adam bunun işe yaradığını orada diyor dba.stackexchange.com/a/36165/55752
scythargon

@scythargon işletim sistemi önbelleğinde bitebilir, PostgreSQL önbellek belleğinde kalmayacaktır. Bana inanmıyorsan yukarıda önerdiklerimi dene.
hbn

SELECT * FROM schema.tablePostGres 9.5'te tüm 60GiB tablonun 100GiB PostgreSQL tampon önbelleğime yüklenmesini denedim ve gördüm.
sudo

1

Benzer bir sorun yaşadım:
Sunucu hizmetini yeniden başlattıktan sonra tüm kasetli veriler düştü, ilk kez denilen birçok sorgu, gerçekten çok yavaş, bütün gerekli endeksler ve veriler kesilinceye kadar sorguların belirli karmaşıklığına neden oldu. Bu, örneğin, kullanıcıların her "öğede" (1-3 sn yürütme süresi) ve ilgili verileri 50 milyon satırdan bir kez vurması gerektiği anlamına gelir, böylece kullanıcılar artık herhangi bir istenmeyen gecikme yaşamaz. Kullanıcıların can sıkıcı kilitlenmeler yaşaması ilk 3 saat sürer, çoğu kullanılan veri yayınlanıncaya ve programlar üretim performansıyla üst seviyelere gelene kadar, en az ilk defa erişilen verilere ulaşırken, birkaç gün kısa bir gecikmeden 2 gün sonra bile bitiyor ... , istatistik verileri vb. için

Bunu çözmek için, büyük dizinleri olan en ağır kullanılan tablolarda seçim yapan küçük bir python betiği yazdı. Koşması 15 dakika sürdü ve performansta gecikme olmadı.


0

Hmmm, COPY komutu olabilir yardımcı olabilir. Sadece stdout ve bundan okumak için COPY'yi yürütün. Pg_dump kullanarak yapmak mümkündür:

pg_dump -U <user> -t <table> <database> > /dev/null

Diğer yol tüm tablo dosyalarını bulmak ve çalıştırmaktır cat <files> > /dev/null.

Tablo dosya adlarının nasıl alınacağına ilişkin örnek:

# SELECT oid, datname FROM pg_database ;
  oid  |  datname  
-------+-----------                                                                                                                                          
<...>
 16384 | test
-- out of database is 16384
# SELECT oid, relname FROM pg_class WHERE relname like 'fn%';
  oid  | relname 
-------+---------
 24576 | fn
(1 row)
-- oid of our table is 24576

öyleyse, tablonun dosyaları / yolu / to / pgsql / data / base / 16384/24576 *

İndeksleri ve tost tablolarını okumak, aynı şekilde kendi sıvılarını almak istersiniz.

BTW, neden ihtiyacınız var? Postgresql ve işletim sisteminin en sıcak verileri önbelleğe almak ve iyi tutmak için yeterince akıllı olduğuna inanıyorum. önbellek verimliliği.


0

Kullandığım RAMDRIVE edildi QSOFT gelen benchmarked Windows için en hızlı ramdisk'in olarak. Az önce kullandım

initdb -D e:\data

burada e: \, RamDisk'in yeridir.


5
Windows'ta PG, bir üretim sitesi için oldukça cesur bir seçimdir, çünkü Windows'ta * nix'ten (RAM'den bağımsız) çok daha yavaştır.
DrColossos
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.