it-swarm.asia

PostgreSQL: Memaksa data ke dalam memori

Apakah ada cara sistematis untuk memaksa PostgreSQL memuat tabel tertentu ke dalam memori, atau setidaknya membacanya dari disk sehingga akan di-cache oleh sistem?

34
Adam Matan

Anda mungkin diinterupsi di salah satu topik milis , dijawab oleh Tom Lane (core dev):

[..] Tapi pendapat saya adalah bahwa orang yang berpikir mereka lebih pintar daripada algoritma caching LRU biasanya keliru. Jika semua tabel itu sangat banyak digunakan, itu akan tetap berada dalam memori dengan baik. Jika itu tidak cukup banyak digunakan untuk tinggal di memori sesuai dengan algoritma LRU, mungkin ruang memori benar-benar harus dihabiskan untuk sesuatu yang lain. [..]

Anda mungkin juga diinterupsi dalam pertanyaan SO: https://stackoverflow.com/questions/486154/postgresql-tentara-tables-tables dan mungkin lebih sesuai - https://stackoverflow.com/questions/407006/need-to-load-the-whole-postgresql-database-into-the-ram

27
DrColossos

Postgres 9.4 akhirnya menambahkan ekstensi untuk preload data dari relasi ke OS atau cache buffer basis data (sesuai pilihan Anda):

pg_prewarm

Ini memungkinkan pencapaian kinerja operasi penuh lebih cepat.

Jalankan sekali di basis data Anda (instruksi detail di sini ):

CREATE EXTENSION pg_prewarm;

Maka mudah untuk melakukan preload relasi yang diberikan. Contoh dasar:

SELECT pg_prewarm('my_tbl');

Menemukan tabel pertama bernama my_tbl di jalur pencarian dan memuatnya ke cache buffer Postgres

Atau:

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

prefetch mengeluarkan permintaan prefink asinkron ke sistem operasi, jika ini didukung, atau melempar kesalahan sebaliknya. read membaca rentang blok yang diminta; tidak seperti prefetch, ini sinkron dan didukung di semua platform dan build, tetapi mungkin lebih lambat. buffer membaca rentang blok yang diminta ke dalam cache buffer database.

Standarnya adalah buffer, yang memiliki dampak terbesar (biaya lebih tinggi, efek terbaik).

Baca manual untuk lebih jelasnya , kutipan berasal dari sana.
Depesz blogged juga.

39

Dalam kasus umum jika Anda memiliki cukup RAM Anda umumnya dapat mempercayai layanan database untuk melakukan pekerjaan dengan baik untuk menjaga hal-hal yang Anda gunakan secara teratur dalam RAM. Beberapa sistem memungkinkan Anda untuk mengisyaratkan bahwa tabel harus selalu diadakan di RAM (yang berguna untuk tabel bertubuh kecil yang tidak sering digunakan tetapi ketika mereka digunakan adalah penting bahwa mereka merespons secepat mungkin) tetapi jika pgsql memiliki tabel seperti itu mengisyaratkan Anda Anda harus sangat berhati-hati dalam menggunakannya karena Anda mengurangi jumlah memori yang tersedia untuk melakukan cache apa pun sehingga Anda dapat memperlambat aplikasi secara keseluruhan.

Jika Anda mencari untuk mengunggulkan halaman cache halaman pada startup (misalnya setelah reboot atau operasi pemeliharaan lainnya yang menyebabkan DB melupakan semua yang di-cache) maka tulis skrip yang melakukan hal berikut:

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

(langkah terakhir diulang untuk setiap indeks, atau kursus, dan berhati-hati untuk memiliki bidang dalam klausa ORDER BY dalam urutan yang benar)

Setelah menjalankan di atas, setiap data dan halaman indeks seharusnya sudah dibaca dan akan berada di halaman cache RAM (setidaknya untuk saat ini). Kami memiliki skrip seperti ini untuk database aplikasi kami, yang dijalankan setelah reboot sehingga pengguna pertama yang masuk ke sistem setelah itu tidak mengalami respons yang lebih lambat. Anda lebih baik menulis tulisan tangan seperti skrip tersebut, daripada memindai tabel definisi db (seperti sys.objects/sys.indexes/sys.columns dalam MSSQL), maka Anda dapat memindai indeks secara selektif yang paling umum digunakan daripada memindai semuanya yang akan memakan waktu lebih lama.

4
David Spillett

Saya punya masalah serupa:
Setelah memulai kembali layanan server dan semua data yang diuangkan turun, banyak pertanyaan yang disebut pertama kali di mana benar-benar lambat, menyebabkan kompleksitas spesifik dari pertanyaan, sampai semua indeks dan data yang diperlukan diuangkan. itu artinya, misalnya pengguna harus menekan setiap "item" (1-3 detik waktu eksekutif) dan data terkait dari 50 juta baris, sehingga pengguna tidak akan mengalami penundaan yang tidak diinginkan lagi. Dibutuhkan 3 jam pertama bagi pengguna untuk mengalami gangguan menjengkelkan, sampai data yang paling banyak digunakan dicairkan dan program merusak kedudukan tertinggi dengan kinerja produksi, berakhir pada saat itu, 2 hari beberapa penundaan singkat yang tiba-tiba, ketika memukul lebih sedikit data yang diakses pertama kali ... , untuk data statistik dll.

Untuk mengatasinya, tulislah skrip python kecil yang melakukan seleksi pada tabel yang paling berat digunakan dengan indeks besar. Butuh 15 menit untuk menjalankan, dan tidak ada penundaan kinerja.

1
LongBeard_Boldy

Saya menggunakan RamDrive dari QSoft, yang benchmark sebagai ramdisk tercepat untuk Windows. Saya baru saja digunakan

initdb -D e:\data

di mana e:\adalah tempat RamDisk.

0
David

Hmmm, mungkin perintah COPY akan membantu. Cukup jalankan COPY ke stdout dan baca darinya. Dimungkinkan untuk melakukannya menggunakan pg_dump:

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

Cara lain adalah menemukan semua file tabel dan menjalankan cat <files> > /dev/null.

Berikut adalah contoh cara mendapatkan nama file tabel:

# 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

jadi, file tabel adalah/path/ke/pgsql/data/base/16384/24576 *

Anda pasti ingin membaca indeks dan tabel roti bakar juga, dapatkan oids mereka dengan cara yang sama.

BTW, mengapa Anda membutuhkannya? Saya percaya postgresql dan OS cukup cerdas untuk menyimpan cache data terpanas dan mempertahankannya. efisiensi cache.

0
rvs