Saya mengalami kesulitan menemukan penjelasan 'awam' tentang bagaimana indeks di-cache di PostgreSQL, jadi saya ingin cek kenyataan pada salah satu atau semua asumsi ini:
- Indeks postgreSQL, seperti baris, hidup di disk tetapi mungkin di-cache.
- Indeks mungkin seluruhnya ada dalam cache atau tidak sama sekali.
- Apakah itu di-cache atau tidak tergantung pada seberapa sering digunakan (seperti yang didefinisikan oleh perencana kueri).
- Untuk alasan ini sebagian besar indeks 'masuk akal' akan berada di cache sepanjang waktu.
- Indeks hidup dalam cache yang sama (the
buffer cache
?) Seperti baris, dan oleh karena itu ruang cache yang digunakan oleh indeks tidak tersedia untuk baris.
Motivasi saya untuk memahami ini mengikuti dari pertanyaan lain saya bertanya di mana disarankan agar indeks parsial dapat digunakan pada tabel di mana sebagian besar data tidak akan pernah diakses.
Sebelum melakukan ini, saya ingin menjelaskan bahwa menggunakan indeks parsial menghasilkan dua keuntungan:
- Kami mengurangi ukuran indeks dalam cache, membebaskan lebih banyak ruang untuk baris di cache.
- Kami mengurangi ukuran B-Tree, menghasilkan respons permintaan yang lebih cepat.
postgresql
performance
index-tuning
cache
dukedave
sumber
sumber
Jawaban:
Bermain sedikit dengan pg_buffercache , saya bisa mendapatkan jawaban atas beberapa pertanyaan Anda.
pg_buffercache
menunjukkan, jawabannya adalah YA yang pasti . Perlu dicatat bahwa data tabel sementara tidak di -cache di sini.EDIT
Saya telah menemukan artikel hebat Jeremiah Peschka tentang penyimpanan tabel dan indeks. Dengan informasi dari sana, saya bisa menjawab (2) juga. Saya membuat tes kecil, jadi Anda bisa memeriksanya sendiri.
Secara keseluruhan, ini menunjukkan bahwa indeks dan tabel dapat di-cache halaman demi halaman, oleh karena itu jawaban untuk (2) adalah TIDAK .
Dan yang terakhir untuk menggambarkan tabel sementara tidak di-cache di sini:
sumber
temp_buffers
) - untuk seluruh tabel atau hanya bagian pada disk. Saya harapkan yang terakhir. Mungkin ujian yang menarik ..Halaman indeks diambil ketika kueri memutuskan mereka akan berguna untuk mengurangi jumlah data tabel yang dibutuhkan untuk menjawab kueri. Hanya blok indeks yang dinavigasi untuk menyelesaikan yang dibaca. Ya, mereka masuk ke kumpulan shared_buffers yang sama di mana data tabel disimpan. Keduanya juga didukung oleh cache sistem operasi sebagai lapisan kedua caching.
Anda dapat dengan mudah memiliki 0,1% dari indeks dalam memori atau 100% dari itu. Gagasan bahwa sebagian besar indeks "masuk akal" akan berada di cache sepanjang waktu "jatuh dengan keras ketika Anda memiliki kueri yang hanya menyentuh sebagian dari tabel. Contoh umum adalah jika Anda memiliki data yang berorientasi waktu. Sering kali mereka biasanya menavigasi ujung meja, jarang melihat sejarah lama. Di sana Anda mungkin menemukan semua blok indeks yang diperlukan untuk menavigasi ke dan di sekitar akhir memori baru-baru ini, sementara sangat sedikit yang diperlukan untuk menavigasi catatan sebelumnya ada di sana.
Bagian rumit dari implementasi bukanlah bagaimana blok masuk ke cache buffer. Itu aturan tentang kapan mereka pergi. My Inside the PostgreSQL Buffer Cache talk dan contoh pertanyaan yang disertakan di sana dapat membantu Anda memahami apa yang terjadi di sana, dan melihat apa yang sebenarnya terakumulasi di server produksi. Ini bisa mengejutkan. Ada banyak lagi tentang semua topik ini di buku PostgreSQL 9.0 Kinerja Tinggi saya juga.
Indeks parsial dapat membantu karena mengurangi ukuran indeks, dan karena itu keduanya lebih cepat untuk menavigasi dan meninggalkan lebih banyak RAM untuk melakukan caching hal-hal lain. Jika navigasi indeks Anda sedemikian rupa sehingga bagian yang Anda sentuh selalu dalam RAM, bagaimanapun, itu mungkin tidak membeli peningkatan nyata sekalipun.
sumber