У меня возникают трудности с поиском «непрофессиональных» объяснений того, как индексы кэшируются в PostgreSQL, поэтому я хотел бы проверить реальность любого или всех этих предположений:
- Индексы PostgreSQL, как и строки, живут на диске, но могут кэшироваться.
- Индекс может быть целиком в кеше или не находиться вообще.
- Кэшируется он или нет, зависит от того, как часто он используется (как определено планировщиком запросов).
- По этой причине самые «разумные» индексы будут постоянно находиться в кеше.
- Индексы находятся в том же кэше (
buffer cache
?), Что и строки, поэтому пространство, используемое индексом, недоступно для строк.
Моя мотивация для понимания этого вытекает из другого вопроса, который я задал, где предлагалось использовать частичные индексы для таблиц, где к большинству данных никогда не будет доступа.
Прежде чем приступить к этому, я хотел бы пояснить, что использование частичного индекса дает два преимущества:
- Мы уменьшаем размер индекса в кеше, освобождая больше места для самих строк в кеше.
- Мы уменьшаем размер B-дерева, что приводит к более быстрому ответу на запрос.
postgresql
performance
index-tuning
cache
dukedave
источник
источник
Ответы:
Немного поиграв с pg_buffercache , я мог бы получить ответы на некоторые ваши вопросы.
pg_buffercache
шоу, ответ является окончательным ДА . Стоит отметить, что данные временных таблиц здесь не кэшируются.РЕДАКТИРОВАТЬ
Я нашел потрясающую статью Иеремии Пешки о хранении таблиц и индексов. С информацией оттуда я мог бы также ответить (2) . Я настроил небольшой тест, чтобы вы могли проверить это самостоятельно.
В общем, это показывает, что индексы и таблицы могут кэшироваться постранично, поэтому ответ на (2) - НЕТ .
И последнее, чтобы проиллюстрировать временные таблицы, не кэшированные здесь:
источник
temp_buffers
) - для всей таблицы или только части на диске. Я ожидал бы последнего. Может быть интересным тестом ..Индексные страницы выбираются, когда запрос решает, что будет полезно сократить объем табличных данных, необходимых для ответа на запрос. Только блоки индекса, по которым осуществляется навигация для выполнения, считываются. Да, они попадают в тот же пул shared_buffers, где хранятся данные таблицы. Оба также поддерживаются кэшем операционной системы как второй уровень кэширования.
Вы можете легко иметь 0,1% индекса в памяти или 100% его. Идея о том, что большинство «разумных» индексов будет постоянно находиться в кэше », не поддается, когда у вас есть запросы, которые касаются только подмножества таблицы. Типичный пример - если у вас есть ориентированные на время данные. Часто они часто перемещаются по последнему концу таблицы, редко просматривая старую историю. Там вы можете найти все индексные блоки, необходимые для навигации по недавнему концу памяти и вокруг него, в то время как очень мало нужно для навигации по более ранним записям.
Сложные части реализации не в том, как блоки попадают в буферный кеш. Это правила, когда они уходят. My Inside the PostgreSQL Buffer Cache и примеры включенных в него запросов могут помочь вам понять, что там происходит, и увидеть, что действительно накапливается на рабочем сервере. Это может быть удивительно. По всем этим темам в моей высокой производительности PostgreSQL 9.0 гораздо больше книге о .
Частичные индексы могут быть полезны, потому что они уменьшают размер индекса и, следовательно, быстрее перемещаются и оставляют больше оперативной памяти для кэширования других вещей. Если ваша навигация по индексу такова, что части, к которым вы прикасаетесь, всегда находятся в оперативной памяти, в любом случае это может не принести реального улучшения.
источник