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ı?
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:
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
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_tbl
Arama yolunda adı verilen ilk tabloyu bulur ve Postgres tampon önbelleğine yükler.
Veya:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
Bu 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; aksineprefetch
, bu senkronize ve tüm platformlarda ve yapılarda desteklenir, ancak daha yavaş olabilir.buffer
istenen 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ı .
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.columns
MSSQL'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 .
SELECT * FROM schema.table
PostGres 9.5'te tüm 60GiB tablonun 100GiB PostgreSQL tampon önbelleğime yüklenmesini denedim ve gördüm.
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ı.
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.
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.