Как отключить оптимизацию postgresql "Cache"?

Я пытаюсь оптимизировать свою функцию.
Дело в том, когда вы запускаете запрос, как только получаете один результат.
Запустите запрос во второй раз или в третий раз, время процесса намного меньше.

SELECT  map.get_near_link(a.X, a.Y, a.azimuth)
FROM traffic.avl;

Первый раз 17 seg

Total query runtime: 17188 ms.
801 rows retrieved.

Второй раз 11 seg

Total query runtime: 11406 ms.
801 rows retrieved.

Я предполагаю, что какой-то кеш делает оптимизацию за сценой. Как я могу отключить это поведение, чтобы получить более реалистичное значение времени выполнения?

Ответ 1

PostgreSQL не имеет оптимизацию "кеша" в смысле кеша результатов запроса.

Он кэширует таблицы, которые недавно были прочитаны в shared_buffers, но для большинства установок, которые имеют небольшой эффект. Основной кеш - это кеш чтения диска операционной системы. Для получения дополнительной информации см.:

Смотрите и очистите кеши/буферы Postgres?

Мне кажется, что у вас есть система с разумным объемом оперативной памяти и быстрый процессор, но очень медленный диск. Таким образом, запросы, которые попадают в кэш-память ОС очень быстро, но запросы, которые идут на диск, занимают пару секунд, чтобы прочитать данные. Таким образом, эффекты кеширования очень сильны.

Вы должны explain (buffers, analyze, verbose) SELECT ... ваши запросы. Попробуйте с несколькими различными входными значениями, пока не получите медленный. Сравните планы.

Если планы совпадают, возможно, это так.

Если планы разные, вы, вероятно, сталкиваетесь с ситуацией, когда планировщик запросов делает неправильный выбор на основе изменений в статистике таблицы. Увеличение целевых показателей статистики для интересующих столбцов может помочь (см. Руководство). Если вы получите разные планы и застряли/хотите помочь, не стесняйтесь публиковать новый вопрос на dba.stackexchange.com с подробностями.

Ответ 2

sync; sudo service postgresql stop; echo 1 > /proc/sys/vm/drop_caches; sudo service postgresql start

Ответ 3

Поскольку вы сказали, что хотите оптимизировать свою функцию, а не свой макет диска, то, возможно, 2-е тайминги - это те, которые вы хотите сосредоточить на этой цели, поскольку они являются самой чистой мерой времени выполнения самой функции, а не время, необходимое для сбора данных для подачи в вашу функцию.

И поскольку время 2-го исполнения по-прежнему составляет 2/3 от первого времени выполнения, все равно будет сосредоточено ваше внимание, даже если вы хотите оптимизировать общее время выполнения.

Если вам действительно нужно это сделать, вы можете очистить кеш, как описано в других ответах, но это обычно слишком обременительно для повседневной работы. Лучше было бы создать программу / script, которая выбирает случайные (но в целом реалистичные) значения a.X, a.Y, a.azimuth и запускает запрос с ними. Меняя значения каждый раз из множества примеров реалий, вы получаете результаты, наиболее представительные в реальном мире. Создание таких драйверов - это немного больше работы, но обычно окупается.