Apakah ada cara sistematis untuk memaksa PostgreSQL memuat tabel tertentu ke dalam memori, atau setidaknya membacanya dari disk sehingga akan di-cache oleh sistem?
Apakah ada cara sistematis untuk memaksa PostgreSQL memuat tabel tertentu ke dalam memori, atau setidaknya membacanya dari disk sehingga akan di-cache oleh sistem?
Jawaban:
Anda mungkin diinterupsi dalam 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 salah. Jika semua tabel itu sangat banyak digunakan, itu akan tetap berada dalam memori dengan baik. Jika tidak cukup banyak digunakan untuk tetap dalam memori sesuai dengan algoritma LRU, mungkin ruang memori benar-benar harus dihabiskan untuk sesuatu yang lain. [..]
Anda mungkin juga diminta pertanyaan SO: https://stackoverflow.com/questions/486154/postgresql-tentara-tabel dan mungkin lebih cocok https://stackoverflow.com/questions/407006/need-to-load-the -whole-postgresql-database-into-the-ram
Postgres 9.4 akhirnya menambahkan ekstensi untuk preload data dari relasi ke OS atau cache buffer database (sesuai pilihan Anda):
pg_prewarm
Ini memungkinkan pencapaian kinerja operasi penuh lebih cepat.
Jalankan sekali di basis data Anda (instruksi terperinci di sini ):
CREATE EXTENSION pg_prewarm;
Maka mudah untuk melakukan preload relasi yang diberikan. Contoh dasar:
SELECT pg_prewarm('my_tbl');
Temukan tabel pertama yang disebutkan my_tbl
di jalur pencarian dan muat ke cache buffer Postgres
Atau:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
masalah permintaan prefink asinkron ke sistem operasi, jika ini didukung, atau melempar kesalahan sebaliknya.read
membaca rentang blok yang diminta; tidak sepertiprefetch
ini, ini sinkron dan didukung pada 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 dari sana.
Depesz juga membuat blog tentang hal itu.
Dalam kasus umum jika Anda memiliki RAM yang cukup, Anda biasanya dapat mempercayai layanan database untuk melakukan pekerjaan yang baik untuk menjaga hal-hal yang Anda gunakan secara teratur dalam RAM. Beberapa sistem memungkinkan Anda untuk mengisyaratkan bahwa tabel harus selalu disimpan dalam RAM (yang berguna untuk tabel bertubuh kecil yang tidak sering digunakan tetapi ketika digunakan, penting bahwa mereka merespons secepat mungkin) tetapi jika pgsql memiliki petunjuk tabel seperti itu 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 demikian juga akan ada dalam cache halaman RAM (untuk saat ini setidaknya). Kami memiliki skrip seperti ini untuk database aplikasi kami, yang dijalankan setelah reboot sehingga pengguna pertama yang masuk ke sistem setelahnya tidak mengalami respons yang lebih lambat. Anda lebih baik menulis skrip semacam itu dengan tangan, daripada memindai tabel definisi db (seperti sys.objects
/ sys.indexes
/ sys.columns
di MSSQL), maka Anda dapat memindai indeks yang paling umum digunakan secara selektif daripada memindai semua yang membutuhkan waktu lebih lama.
SELECT * FROM schema.table
dan melihatnya memuat seluruh tabel 60GiB ke dalam cache buffer 100GiB PostgreSQL saya.
Saya memiliki masalah yang sama:
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 data akses pertama yang kurang diakses ... , untuk data statistik dll.
Untuk mengatasi ini, tulis 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.
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 menjalankannya 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 juga ingin membaca indeks dan tabel roti bakar juga, mendapatkan 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.
Saya menggunakan ramdrive dari QSoft, yang mengacu sebagai ramdisk tercepat untuk Windows. Saya baru saja digunakan
initdb -D e:\data
di mana e: \ adalah tempat RamDisk.