Существует ли систематический способ заставить PostgreSQL загрузить определенную таблицу в память или хотя бы прочитать ее с диска, чтобы она была кэширована системой?
Существует ли систематический способ заставить PostgreSQL загрузить определенную таблицу в память или хотя бы прочитать ее с диска, чтобы она была кэширована системой?
Ответы:
Вы можете быть заинтересованы в одной из тем списков рассылки , на которую отвечает Том Лейн (основной разработчик):
[..] Но я считаю, что люди, которые думают, что они умнее алгоритма кэширования LRU, обычно ошибаются. Если таблица используется очень интенсивно, она просто останется в памяти. Если он не используется достаточно интенсивно, чтобы оставаться в памяти в соответствии с алгоритмом LRU, возможно, пространство памяти действительно должно быть потрачено на что-то другое. [..]
Вы также можете быть заинтересованы в SO вопросе: https://stackoverflow.com/questions/486154/postgresql-teilitary-tables и, возможно, более удобные https://stackoverflow.com/questions/407006/need-to-load-the -whole-PostgreSQL-базы данных в самом баран
В Postgres 9.4 наконец-то добавлено расширение для предварительной загрузки данных из отношений в ОС или буферный кеш базы данных (на ваш выбор):
pg_prewarm
Это позволяет быстрее достичь полной производительности.
Запустите один раз в вашей базе данных (подробные инструкции здесь ):
CREATE EXTENSION pg_prewarm;
Тогда просто предварительно загрузить любое данное отношение. Основной пример:
SELECT pg_prewarm('my_tbl');
Находит первую таблицу с именем my_tbl
в пути поиска и загружает ее в буферный кеш Postgres
Или:
SELECT pg_prewarm('my_schema.my_tbl', 'prefetch');
prefetch
выдает асинхронные запросы предварительной выборки в операционную систему, если это поддерживается, или выдает ошибку в противном случае.read
читает запрошенный диапазон блоков; в отличие отprefetch
этого, это синхронно и поддерживается на всех платформах и сборках, но может быть медленнее.buffer
считывает запрошенный диапазон блоков в буферный кеш базы данных
По умолчанию buffer
используется наибольшее влияние (более высокая стоимость, лучший эффект).
Прочитайте руководство для более подробной информации , цитаты оттуда.
Депеш тоже писал об этом.
В общем случае, если у вас достаточно ОЗУ, вы, как правило, можете доверять службе базы данных, чтобы хорошо хранить вещи, которые вы регулярно используете в ОЗУ. Некоторые системы позволяют намекать, что таблица всегда должна храниться в оперативной памяти (что полезно для небольших таблиц, которые не используются часто, но при их использовании важно, чтобы они отвечали как можно быстрее), но если pgsql имеет такие табличные подсказки вы должны быть очень осторожны при их использовании, так как вы уменьшаете объем памяти, доступной для кэширования чего-либо еще, чтобы вы могли замедлить работу вашего приложения в целом.
Если вы хотите заполнить кеш страниц базы данных при запуске (например, после перезагрузки или другой операции сопровождения, которая заставляет БД забыть обо всем, что кэшируется), тогда напишите сценарий, который выполняет следующее:
SELECT * FROM <table>
SELECT <primary key fields> FROM <table> ORDER BY <primary key fields>
SELECT <indexed fields> FROM <table> ORDER BY <indexed fields>
(последний шаг повторяется для каждого индекса или курса, и соблюдайте осторожность, чтобы поля в предложении ORDER BY располагались в правильном порядке)
После выполнения вышеуказанного все данные и страница индекса должны быть прочитаны, и поэтому они будут находиться в кеше страницы ОЗУ (по крайней мере, на данный момент) У нас есть подобные сценарии для наших баз данных приложений, которые запускаются после перезагрузки, так что первые пользователи, входящие в систему впоследствии, не испытывают более медленной реакции. Вам лучше писать вручную любой такой сценарий, а не сканировать таблицы определения БД (например, sys.objects
/ sys.indexes
/ sys.columns
в MSSQL), тогда вы можете выборочно сканировать наиболее часто используемые индексы, а не сканировать все, что займет больше времени.
SELECT * FROM schema.table
и увидел, как он загружает всю таблицу 60 ГБ в мой буферный кеш 100GiB PostgreSQL.
У меня была похожая проблема:
после перезапуска службы сервера и отбрасывания всех кэшированных данных, многие запросы, вызываемые впервые, были действительно очень медленными, вызывая особую сложность запросов, пока все необходимые индексы и данные не были кэшированы. это означает, что, например, пользователи должны нажимать один раз на каждый «элемент» (время выполнения 1-3 секунды) и связанные данные из 50 миллионов строк, чтобы пользователи больше не испытывали никаких нежелательных задержек. Первые 3 часа пользователи испытывают навязчивые зависания, до тех пор, пока большинство используемых данных не кэшируются, а программы не достигают высочайшего уровня с производственной производительностью, а заканчиваются даже тогда, 2 дня - несколько внезапных коротких задержек, когда достигается меньшее количество обращающихся к ним данных в первый раз ... , для статистических данных и т. д.
Чтобы решить эту проблему, мы написали небольшой скрипт на python, который выполняет выборки для самых тяжелых таблиц с большими индексами. Это заняло 15 минут, и никаких задержек в производительности.
Хм, может быть, команда COPY поможет. Просто выполните COPY для stdout и прочитайте его. Это можно сделать с помощью pg_dump:
pg_dump -U <user> -t <table> <database> > /dev/null
Другой способ - найти все файлы таблиц и запустить cat <files> > /dev/null
.
Вот пример того, как получить имена файлов таблиц:
# 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
Итак, файл (ы) таблицы: / path / to / pgsql / data / base / 16384/24576 *
Вы хотите также прочитать индексы и таблицы тостов, получить их oids таким же образом.
Кстати, зачем тебе это? Я считаю, что postgresql и ОС достаточно умны, чтобы кэшировать самые горячие данные и поддерживать их в хорошем состоянии. эффективность кеша.
Я использую RAMDrive из QSoft, который был протестированным как самым быстрым псевдодиск для Windows. Я просто использовал
initdb -D e:\data
где e: \ - это место RamDisk.