Чи є систематичний спосіб змусити PostgreSQL завантажити певну таблицю в пам'ять або принаймні прочитати її з диска, щоб вона кешувалась системою?
Чи є систематичний спосіб змусити PostgreSQL завантажити певну таблицю в пам'ять або принаймні прочитати її з диска, щоб вона кешувалась системою?
Відповіді:
Вас може зацікавити одна з тем списків розсилки , на яку відповідає Том Лейн (core dev):
[..] Але я вважаю, що люди, які вважають, що вони розумніші за алгоритм кешування LRU, зазвичай помиляються. Якщо таблиця все сильно використовується, вона залишиться в пам'яті просто чудово. Якщо він недостатньо активно використовується для зберігання в пам'яті згідно алгоритму LRU, можливо, простір пам'яті дійсно слід витратити на щось інше. [..]
Можливо, ви також зацікавитеся питанням про так: https://stackoverflow.com/questions/486154/postgresql-temporary-tables та, можливо, більш підходящий https://stackoverflow.com/questions/407006/need-to-load-the -whole-postgresql-database-into-the-ram
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>
(останній крок повторюється для кожного індексу чи курсу, і будьте обережні, щоб поля в пункті ЗАМОВЛЕННЯ В правильному порядку були)
Після виконання вищезазначеного кожна сторінка даних та покажчиків повинна була бути прочитана, і така буде в кеш-пам'яті сторінки ОЗУ (поки щонайменше). У нас є такі сценарії для наших баз даних додатків, які запускаються після перезавантаження, так що перші користувачі, які входять у систему після цього, не відчувають повільної реакції. Вам краще вручну писати будь-який подібний сценарій, а не сканувати таблиці визначення db (як sys.objects
/ sys.indexes
/ sys.columns
в MSSQL), тоді ви можете вибірково сканувати індекси, які найчастіше використовуються, а не сканувати все, що займе більше часу.
SELECT * FROM schema.table
і побачив, як він завантажує всю таблицю 60GiB в мій буфер кешу 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
таким чином, файли таблиці є / шлях / до / pgsql / дані / база / 16384/24576 *
Ви migth хочете також читати індекси та тости таблиці, отримувати їхні одинакові способи.
До речі, навіщо це потрібно? Я вважаю, що postgresql і ОС досить розумні, щоб кешувати найгарячіші дані та підтримувати добро. ефективність кешу
Я використовую RAMDrive з QSoft, який був протестованим як найшвидшим псевдодіск для Windows. Я просто використовував
initdb -D e:\data
де e: \ - місце RamDisk.