PostgreSQL: форсувати дані в пам'ять


32

Чи є систематичний спосіб змусити PostgreSQL завантажити певну таблицю в пам'ять або принаймні прочитати її з диска, щоб вона кешувалась системою?

Відповіді:


25

Вас може зацікавити одна з тем списків розсилки , на яку відповідає Том Лейн (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


1
+1 Ця ж ідея стосується і інших RDBMS.
gbn

25
Так і ні. Ми замикаємо деякі таблиці Oracle у пам’яті, оскільки ми знаємо, що вони можуть використовуватися не так часто, але в ситуації, яку вони використовують, затримка стане вбивцею. БД повинен завжди давати остаточне слово DBA (інший приклад - натяк на оптимізатор запитів).
Гай

35

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це найбільший вплив (більша вартість, найкращий ефект).

Прочитайте посібник для більш детальної інформації , цитати - звідти. Про це теж
блогував Депес .


4

У загальному випадку, якщо у вас є достатня кількість оперативної пам’яті, ви, як правило, можете довіряти службі баз даних, щоб зробити гарну роботу по збереженню речей, які ви регулярно використовуєте в оперативній пам’яті. Деякі системи дозволяють вам натякнути, що таблиця завжди повинна зберігатися в оперативній пам’яті (що корисно для невеликих таблиць, які використовуються не часто, але коли вони використовуються, важливо, щоб вони відповідали якомога швидше), але якщо 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), тоді ви можете вибірково сканувати індекси, які найчастіше використовуються, а не сканувати все, що займе більше часу.


3
Це не працюватиме, принаймні, на PostgreSQL. Невеликий (256 КБ) кільцевий буфер виділяється із спільних буферів для послідовного сканування, щоб запобігти використанню всього кешу буфера. Докладні відомості див. У github.com/postgres/postgres/blob/master/src/backend/storage/… . Ви можете перевірити це, зробивши SELECT * з великої таблиці, потім переглянувши таблицю pg_buffercache (з розширення pg_buffercache).
hbn

@hbn привіт там, але цей хлопець у цій темі збереження каже, що це працює - dba.stackexchange.com/a/36165/55752
scythargon

@scythargon може закінчитися в кеші ОС, він не отримає його в кеш-пам'яті PostgreSQL. Спробуйте те, що я запропонував вище, якщо ви мені не вірите.
hbn

У Postgres 9.5 я спробував SELECT * FROM schema.tableі побачив, як він завантажує всю таблицю 60GiB в мій буфер кешу 100GiB PostgreSQL.
судо

1

У мене була подібна проблема:
Після перезапуску серверної служби та відкидання всіх даних, багато запитів викликали перший раз, коли дійсно дуже повільно, що викликає особливу складність запитів, доки всі необхідні індекси та дані не були введені в касу. це означає, що, наприклад, користувачі повинні натискати один раз на кожен "елемент" (1-3 секунди часу виконання) та пов’язані з ним дані з 50 мільйонів рядків, так що користувачі більше не зазнають небажаних затримок. Перші 3 години споживачі потребують роздратованих зависань, поки більшість використовуваних даних не буде знято, а програми руйнують першокласні показники з продуктивністю, закінчуючи навіть тоді, 2 дні, кілька раптових коротких затримок, коли потрапляє менше даних, що вперше отримують доступ ... , для статистичних даних тощо

Для вирішення цього питання написав невеликий скрипт python, який виконує вибір на найважчих таблицях, що використовуються, з великими індексами. Пробіг зайняв 15 хв., І жодних затримок роботи не було.


0

Гммм, може допомогти команда 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 і ОС досить розумні, щоб кешувати найгарячіші дані та підтримувати добро. ефективність кешу


0

Я використовую RAMDrive з QSoft, який був протестованим як найшвидшим псевдодіск для Windows. Я просто використовував

initdb -D e:\data

де e: \ - місце RamDisk.


5
PG в Windows - досить сміливий вибір для виробничого сайту, оскільки він набагато повільніше, ніж у * nix (незалежно від оперативної пам'яті).
DrColossos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.