SlideShare a Scribd company logo
Рецепты оптимизации производительности PostgreSQL
Алексей Ермаков
alexey.ermakov@postgresql-consulting.com
2
О чем сегодня будем говорить
• В каких местах системы могут быть проблемы
• Что можно сделать и какие гайки крутить
• Как искать узкие места
3
Типичный веб проект
[client]⇐⇒ [web server]⇐⇒ [application]⇐⇒ [database]
4
Все ли у нас в порядке?
Не все метрики одинаково полезны для оценки производительности
• LA, CPU load, %diskutil, memory usage и т.п. нужны, но не всегда помогают
• Среднее время выполнения http запроса – как средняя температура по
больнице
• Быстрый ответ конечно хорошо, но только если это не 5xx ошибка
5
Все ли у нас в порядке?
График количества медленных (> 333ms) http запросов в минуту
6
Все ли у нас в порядке?
График распределения http запросов по времени, в % в минуту
7
Все ли у нас в порядке?
График количества 4xx и 5xx ошибок в секунду
8
Все ли у нас в порядке?
Прежде чем крутить гайки стоит иметь какие-то метрики для оценки
эффекта от изменений!
9
Где могут быть проблемы?
Не модель OSI, но...
10
Длинные транзакции
• Очень плохо для базы из-за реализации multiversion concurrency control
(MVCC)
• При каждом update строки создается ее копия
• Ненужные копии подчищаются процессом autovacuum
• Пока длинная транзакция открыта, автовакуум не может их почистить
11
Длинные транзакции
• Приводят к распуханию (bloat) таблиц и индексов
• Запросы могут работать медленней из-за необходимости сканировать
неактуальные версии строк
• Освободить уже занятое место не всегда просто
12
Длинные транзакции
Как бороться?
• Мониторинг длины самой долгой транзакции (на репликах с
hot_standby_feedback = on тоже!)
• Автоматически прибивать по крону (см. pg_terminate_backend(),
pg_stat_activity)
• Разграничение пользователей по допустимому времени ответа
• Модифицировать приложение
• pg_dump ⇒ pg_basebackup
13
ORM
• Для сложных выборок запросы лучше писать самостоятельно
• Не вызывать запросы в циклах без сильной необходимости
• Не стоит ожидать что запрос с 20 joins будет работать быстро
• Комментарии с ip/hostname/appname/stacktrace бывают полезны
14
SQL запросы это не только select и join
• [recursive]CTE
• Window functions
• Lateral join
• DISTINCT ON
• EXISTS / NOT EXISTS
• generate_series()
• Arrays
• hstore/json/jsonb
• COPY
• Materialized views
• Unlogged tables
• pl/* functions
Нет времени объяснять, надо использовать!
15
SQL запросы это не только select и join
Выборка TOP N по списку
SELECT *
FROM (
VALUES (29),(68),(45),(47),(50),(41),(11),(4),(83),(60)
) AS t(category_id),
LATERAL (
SELECT * FROM posts WHERE posts.category_id = t.category_id ORDER BY created_at DESC LIMIT 5
) AS _t;
16
SQL запросы это не только select и join
Одним запросом к базе можно производить почти любые вычисления
17
Хватает ли сети?
Latency
• Оптимально, когда сервера подключены в один switch
• ping между приложением и базой ≈ 0.1ms
• Если приложение делает много запросов – то критичный параметр
18
Хватает ли сети?
Bandwidth
• Расходы на репликацию
• pg_basebackup --max-rate
• Несколько интерфейсов, bonding, 10Gbps
19
Connection pooling: pgbouncer
max_client_connections pool_size
• 1 connect to DB = 1 process (postgresql backend)
• pool_mode = (session|transaction|statement)
20
Connection pooling: pgbouncer
• pool_mode = transaction, если возможно
• Помним о сессионных переменных, prepared statements
• pool_size = (10|20|30)
• max_client_connections = (1000|10000)
21
Какую версию PostgreSQL использовать?
• Поддерживаемые версии: 9.1-9.5
• Последняя минорная версия
22
postgresql.conf
shared_buffers
• по-умолчанию 32MB/128MB
• 25% доступной RAM – хорошая отправная точка
• 75% – может быть хорошо, если база помещается в память
23
postgresql.conf
Двойное кэширование
shared_buffers
кэш ОС
диски
24
postgresql.conf
• work_mem – внутренняя память процесса для сортировки/hash таблицы.
по-умолчанию 1MB/4MB
• maintenance_work_mem
• effective_cache_size – подсказка планировщику о размере кэша
25
postgresql.conf
autovacuum
• autovacuum_vacuum_scale_factor по-умолчанию 0.2 (20% таблицы)
• autovacuum_analyze_scale_factor по-умолчанию 0.1 (10% таблицы)
• autovacuum_max_workers
• autovacuum_vacuum_cost_delay
26
postgresql.conf
WAL
• synchronous_commit = on (можно выключить, если не справляются диски, но
нужно понимать последствия)
• wal_writer_delay = 200ms..10s
• fsync = on (не выключать!)
27
postgresql.conf
checkpointer
• checkpoint_segments (до 9.5)
• min_wal_size/max_wal_size (9.5+)
• checkpoint_timeout
• checkpoint_completion_target
28
Как искать проблемные запросы?
• логгирование запросов вместе с временем выполнения через
log_min_duration_statement
• парсинг логов через pgfouine, pgbadger, loganalyzer
• pg_stat_statements (9.2+)
29
Как искать проблемные запросы?
pgday=# select * from (select unnest(proargnames) from pg_proc where proname = ’pg_stat_statements’)
unnest
---------------------
userid
dbid
query
calls
total_time
rows
...
blk_read_time
blk_write_time
30
Как искать проблемные запросы?
• track_io_timing = on (на экзотических платформах проверить overhead через
pg_test_timing)
• track_functions = (none|pl|all)
• track_activity_query_size
• pg_stat_statements.max = 10000
• pg_stat_statements.track = (top|all)
• pg_stat_statements.track_utility = off
• pg_stat_statements_reset()
31
Как искать проблемные запросы?
sql/global_reports/query_stat_total.sql
total time: 82:08:45 (IO: 1.56%)
total queries: 3,366,257,532 (unique: 9,072)
report for all databases, version 0.9.3 @ PostgreSQL 9.5.2
tracking top 10000 queries, logging 100ms+ queries
==================================================================================================
pos:1 total time: 20:42:35 (25.2%, CPU: 25.6%, IO: 0.0%) calls: 1,824 (0.00%)
avg_time: 40874.96ms (IO: 0.0%)
user: bravo db: echo rows: 96,797,801,178 query:
SELECT * FROM oscar_recent WHERE id > ?
32
Как ускорить запрос?
• Достаем из логов параметры запроса
• Выполняем explain analyze запроса с данными параметрами
• Смотрим на план, медитируем
• В сложных случаях смотрим на что тратится время на explain.depesz.com
• Если не хватает индексов – добавляем
• Если планировщик не прав, пробуем получить другие планы
33
Как ускорить запрос?
QUERY PLAN
--------------------------------------------------------------------------------------------------
Seq Scan on oscar_recent (cost=0.00..855857.35 rows=62938380 width=42)
(actual time=0.018..9436.857 rows=63020558 loops=1)
Filter: (id > ’3244145575’::bigint)
Planning time: 0.093 ms
Execution time: 11188.941 ms
34
Как ускорить запрос?
Методы получения данных
• seq scan - последовательное чтение таблицы
• index scan - random io (чтение индекса + чтение таблицы)
• index only scan (9.2+)1
• bitmap index scan - компромисс между seq scan/index scan, возможность
использования нескольких индексов в OR/AND условиях
1
https://wiki.postgresql.org/wiki/Index-only_scans
35
Как ускорить запрос?
Методы соединения данных
• nested loop - оптимален для небольших наборов данных
• hash join - оптимален для больших наборов данных
• merge join - оптимален для больших наборов данных, в случае, если они
отсортированы
36
Как ускорить запрос?
Какие бывают индексы?
• partial
create index concurrently ... on post using btree(domain_id, created)
where pinned = true;
• multicolumn
create index concurrently ... on events using btree(user_id, type);
• functional
create index concurrently ... on i_movement
using btree((coalesce(m_movement_id, 0)));
• btree/gin/gist/brin
37
Система
• Linux: Debian/Ubuntu/CentOS/RHEL
• в kernel 3.2 есть некоторые проблемы с IO2
• I/O scheduler: noop, deadline, cfq
• ionice/renice background процессам
2
http://www.databasesoup.com/2014/09/why-you-need-to-avoid-linux-kernel-32.html
38
Система
sysctl.conf
• по-умолчанию vm.dirty_ratio = 20, vm.dirty_background_ratio = 10
• vm.dirty_bytes
• vm.dirty_background_bytes
• vm.swappiness = 1 (swap лучше иметь, но он не должен использоваться)
39
Файловая система
• ext4/xfs
• noatime
• barrier=0 (при наличии raid контроллера с "батарейкой")
40
Диски
• SSD (server grade!)
• SAS 15k
• SATA
41
RAID
• RAID 10
• контроллер с "батарейкой"(BBU)
• cache mode write back
42
RAM
• В один сервер можно поставить сравнительно много 128GB-256GB-...
• Хорошо, когда активно используемая часть базы помещается в память
• Для больших объемов имеет смысл включить huge pages (9.2, 9.4+)3
3
https://habrahabr.ru/post/228793/
43
CPU
• Обычно не является лимитирующим фактором, но не всегда
• Для многопроцессорных систем следует выключать NUMA4:
• numa → off (node interleaving → enabled) в BIOS
• или vm.zone_reclaim_mode = 0 в sysctl.conf
4
http://frosty-postgres.blogspot.ru/2012/08/postgresql-numa-and-zone-reclaim-mode.html
44
Заключение
• Нужны метрики производительности системы
• Потенциальных узких мест в системе может быть много
• Возможности по обработке данных у SQL запросов очень большие
• Для поиска проблемных запросов парсим логи или используем
pg_stat_statements
• Для оптимизации запросов нужно уметь читать вывод explain
• К выбору железа нужно подходить с умом
45
Полезные ссылки
• Different Approaches for MVCC used in well known Databases
• depesz: Explaining the unexplainable
• Объясняя необъяснимое
• https://github.com/PostgreSQL-Consulting/pg-utils
• http://blog.postgresql-consulting.com/
46
Вопросы?
alexey.ermakov@postgresql-consulting.com

More Related Content

PDF
Where is the space, Postgres?
PDF
Как читать и интерпретировать вывод команды EXPLAIN
PDF
Введение в отладку производительности MySQL приложений
PDF
#RuPostgresLive 4: как писать и читать сложные SQL-запросы
PDF
Новые возможности отладки MySQL 5.7 на практике
PPTX
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
PDF
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Where is the space, Postgres?
Как читать и интерпретировать вывод команды EXPLAIN
Введение в отладку производительности MySQL приложений
#RuPostgresLive 4: как писать и читать сложные SQL-запросы
Новые возможности отладки MySQL 5.7 на практике
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Долгожданный релиз pg_pathman 1.0 / Александр Коротков, Дмитрий Иванов (Post...
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)

What's hot (20)

PDF
Hacking PostgreSQL. Разделяемая память и блокировки.
PDF
Лекция 10. Apache Mahout
PDF
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
PDF
"Деплой кода процедур" Мурат Кабилов (Avito)
PDF
Отладка и устранение проблем в PostgreSQL Streaming Replication.
PDF
Devconf2012 what-is-mariadb-5.5
ODP
Hacking PostgreSQL. Физическое представление данных
PPTX
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
PDF
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
PDF
Магия в Python: Дескрипторы. Что это?
PDF
Оптимизация производительности Python
PDF
20130429 dynamic c_c++_program_analysis-alexey_samsonov
PDF
Михаил Давыдов — JavaScript: Асинхронность
PDF
Мир Python функционалим с помощью библиотек
PDF
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
PPTX
Query perfomance tuning
PDF
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
PDF
Архитектура и новые возможности B-tree
PDF
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
PDF
Web осень 2013 лекция 1
Hacking PostgreSQL. Разделяемая память и блокировки.
Лекция 10. Apache Mahout
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
"Деплой кода процедур" Мурат Кабилов (Avito)
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Devconf2012 what-is-mariadb-5.5
Hacking PostgreSQL. Физическое представление данных
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
Магия в Python: Дескрипторы. Что это?
Оптимизация производительности Python
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Михаил Давыдов — JavaScript: Асинхронность
Мир Python функционалим с помощью библиотек
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
Query perfomance tuning
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Архитектура и новые возможности B-tree
Доклад Антона Поварова на Tarantool Meetup. "Tarantool в Badoo: хранение исто...
Web осень 2013 лекция 1
Ad

Viewers also liked (9)

PDF
Using PostgreSQL statistics to optimize performance
PDF
PostgreSQL Meetup Berlin at Zalando HQ
PDF
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
PDF
Autovacuum, explained for engineers, new improved version PGConf.eu 2015 Vienna
PDF
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
PDF
Streaming replication in practice
PDF
Linux tuning to improve PostgreSQL performance
PDF
Troubleshooting PostgreSQL Streaming Replication
PDF
Deep dive into PostgreSQL statistics.
Using PostgreSQL statistics to optimize performance
PostgreSQL Meetup Berlin at Zalando HQ
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
Autovacuum, explained for engineers, new improved version PGConf.eu 2015 Vienna
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
Streaming replication in practice
Linux tuning to improve PostgreSQL performance
Troubleshooting PostgreSQL Streaming Replication
Deep dive into PostgreSQL statistics.
Ad

Similar to PostgreSQL performance recipes (20)

PDF
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
PDF
Народные средства оптимизации PostgreSQL
PDF
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
PDF
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
PDF
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
PDF
Иван Фролков
PPTX
Диагностика postgresql для системного администратора
PDF
Optimization of a big PostgreSQL database
PDF
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
PPT
SAMag2007 Conference: PostgreSQL 8.3 presentation
PDF
Postgresql v509
PPT
поиск узких мест в производительности My sql ботанический определитель. г. ру...
PDF
Распространенные ошибки применения баз данных (Сергей Аверин)
PDF
Не все базы данных одинаково полезны
PDF
Не все базы данных одинаково полезны
PDF
Выступление Сергея Аверина, Badoo, на High Performance Conference
PPTX
Оптимизации скорости выполнения запросов
PDF
Владимир Бородин - PostgreSQL
PDF
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
PDF
История небольшого успеха с PostgreSQL – Владимир Бородин
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Народные средства оптимизации PostgreSQL
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
PostgreSQL: практические примеры оптимизации SQL-запросов / Иван Фролков (Po...
Иван Фролков
Диагностика postgresql для системного администратора
Optimization of a big PostgreSQL database
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
SAMag2007 Conference: PostgreSQL 8.3 presentation
Postgresql v509
поиск узких мест в производительности My sql ботанический определитель. г. ру...
Распространенные ошибки применения баз данных (Сергей Аверин)
Не все базы данных одинаково полезны
Не все базы данных одинаково полезны
Выступление Сергея Аверина, Badoo, на High Performance Conference
Оптимизации скорости выполнения запросов
Владимир Бородин - PostgreSQL
Эксперименты с Postgres в Docker и облаках — оптимизация настроек и схемы ва...
История небольшого успеха с PostgreSQL – Владимир Бородин

PostgreSQL performance recipes

  • 1. Рецепты оптимизации производительности PostgreSQL Алексей Ермаков alexey.ermakov@postgresql-consulting.com
  • 2. 2 О чем сегодня будем говорить • В каких местах системы могут быть проблемы • Что можно сделать и какие гайки крутить • Как искать узкие места
  • 3. 3 Типичный веб проект [client]⇐⇒ [web server]⇐⇒ [application]⇐⇒ [database]
  • 4. 4 Все ли у нас в порядке? Не все метрики одинаково полезны для оценки производительности • LA, CPU load, %diskutil, memory usage и т.п. нужны, но не всегда помогают • Среднее время выполнения http запроса – как средняя температура по больнице • Быстрый ответ конечно хорошо, но только если это не 5xx ошибка
  • 5. 5 Все ли у нас в порядке? График количества медленных (> 333ms) http запросов в минуту
  • 6. 6 Все ли у нас в порядке? График распределения http запросов по времени, в % в минуту
  • 7. 7 Все ли у нас в порядке? График количества 4xx и 5xx ошибок в секунду
  • 8. 8 Все ли у нас в порядке? Прежде чем крутить гайки стоит иметь какие-то метрики для оценки эффекта от изменений!
  • 9. 9 Где могут быть проблемы? Не модель OSI, но...
  • 10. 10 Длинные транзакции • Очень плохо для базы из-за реализации multiversion concurrency control (MVCC) • При каждом update строки создается ее копия • Ненужные копии подчищаются процессом autovacuum • Пока длинная транзакция открыта, автовакуум не может их почистить
  • 11. 11 Длинные транзакции • Приводят к распуханию (bloat) таблиц и индексов • Запросы могут работать медленней из-за необходимости сканировать неактуальные версии строк • Освободить уже занятое место не всегда просто
  • 12. 12 Длинные транзакции Как бороться? • Мониторинг длины самой долгой транзакции (на репликах с hot_standby_feedback = on тоже!) • Автоматически прибивать по крону (см. pg_terminate_backend(), pg_stat_activity) • Разграничение пользователей по допустимому времени ответа • Модифицировать приложение • pg_dump ⇒ pg_basebackup
  • 13. 13 ORM • Для сложных выборок запросы лучше писать самостоятельно • Не вызывать запросы в циклах без сильной необходимости • Не стоит ожидать что запрос с 20 joins будет работать быстро • Комментарии с ip/hostname/appname/stacktrace бывают полезны
  • 14. 14 SQL запросы это не только select и join • [recursive]CTE • Window functions • Lateral join • DISTINCT ON • EXISTS / NOT EXISTS • generate_series() • Arrays • hstore/json/jsonb • COPY • Materialized views • Unlogged tables • pl/* functions Нет времени объяснять, надо использовать!
  • 15. 15 SQL запросы это не только select и join Выборка TOP N по списку SELECT * FROM ( VALUES (29),(68),(45),(47),(50),(41),(11),(4),(83),(60) ) AS t(category_id), LATERAL ( SELECT * FROM posts WHERE posts.category_id = t.category_id ORDER BY created_at DESC LIMIT 5 ) AS _t;
  • 16. 16 SQL запросы это не только select и join Одним запросом к базе можно производить почти любые вычисления
  • 17. 17 Хватает ли сети? Latency • Оптимально, когда сервера подключены в один switch • ping между приложением и базой ≈ 0.1ms • Если приложение делает много запросов – то критичный параметр
  • 18. 18 Хватает ли сети? Bandwidth • Расходы на репликацию • pg_basebackup --max-rate • Несколько интерфейсов, bonding, 10Gbps
  • 19. 19 Connection pooling: pgbouncer max_client_connections pool_size • 1 connect to DB = 1 process (postgresql backend) • pool_mode = (session|transaction|statement)
  • 20. 20 Connection pooling: pgbouncer • pool_mode = transaction, если возможно • Помним о сессионных переменных, prepared statements • pool_size = (10|20|30) • max_client_connections = (1000|10000)
  • 21. 21 Какую версию PostgreSQL использовать? • Поддерживаемые версии: 9.1-9.5 • Последняя минорная версия
  • 22. 22 postgresql.conf shared_buffers • по-умолчанию 32MB/128MB • 25% доступной RAM – хорошая отправная точка • 75% – может быть хорошо, если база помещается в память
  • 24. 24 postgresql.conf • work_mem – внутренняя память процесса для сортировки/hash таблицы. по-умолчанию 1MB/4MB • maintenance_work_mem • effective_cache_size – подсказка планировщику о размере кэша
  • 25. 25 postgresql.conf autovacuum • autovacuum_vacuum_scale_factor по-умолчанию 0.2 (20% таблицы) • autovacuum_analyze_scale_factor по-умолчанию 0.1 (10% таблицы) • autovacuum_max_workers • autovacuum_vacuum_cost_delay
  • 26. 26 postgresql.conf WAL • synchronous_commit = on (можно выключить, если не справляются диски, но нужно понимать последствия) • wal_writer_delay = 200ms..10s • fsync = on (не выключать!)
  • 27. 27 postgresql.conf checkpointer • checkpoint_segments (до 9.5) • min_wal_size/max_wal_size (9.5+) • checkpoint_timeout • checkpoint_completion_target
  • 28. 28 Как искать проблемные запросы? • логгирование запросов вместе с временем выполнения через log_min_duration_statement • парсинг логов через pgfouine, pgbadger, loganalyzer • pg_stat_statements (9.2+)
  • 29. 29 Как искать проблемные запросы? pgday=# select * from (select unnest(proargnames) from pg_proc where proname = ’pg_stat_statements’) unnest --------------------- userid dbid query calls total_time rows ... blk_read_time blk_write_time
  • 30. 30 Как искать проблемные запросы? • track_io_timing = on (на экзотических платформах проверить overhead через pg_test_timing) • track_functions = (none|pl|all) • track_activity_query_size • pg_stat_statements.max = 10000 • pg_stat_statements.track = (top|all) • pg_stat_statements.track_utility = off • pg_stat_statements_reset()
  • 31. 31 Как искать проблемные запросы? sql/global_reports/query_stat_total.sql total time: 82:08:45 (IO: 1.56%) total queries: 3,366,257,532 (unique: 9,072) report for all databases, version 0.9.3 @ PostgreSQL 9.5.2 tracking top 10000 queries, logging 100ms+ queries ================================================================================================== pos:1 total time: 20:42:35 (25.2%, CPU: 25.6%, IO: 0.0%) calls: 1,824 (0.00%) avg_time: 40874.96ms (IO: 0.0%) user: bravo db: echo rows: 96,797,801,178 query: SELECT * FROM oscar_recent WHERE id > ?
  • 32. 32 Как ускорить запрос? • Достаем из логов параметры запроса • Выполняем explain analyze запроса с данными параметрами • Смотрим на план, медитируем • В сложных случаях смотрим на что тратится время на explain.depesz.com • Если не хватает индексов – добавляем • Если планировщик не прав, пробуем получить другие планы
  • 33. 33 Как ускорить запрос? QUERY PLAN -------------------------------------------------------------------------------------------------- Seq Scan on oscar_recent (cost=0.00..855857.35 rows=62938380 width=42) (actual time=0.018..9436.857 rows=63020558 loops=1) Filter: (id > ’3244145575’::bigint) Planning time: 0.093 ms Execution time: 11188.941 ms
  • 34. 34 Как ускорить запрос? Методы получения данных • seq scan - последовательное чтение таблицы • index scan - random io (чтение индекса + чтение таблицы) • index only scan (9.2+)1 • bitmap index scan - компромисс между seq scan/index scan, возможность использования нескольких индексов в OR/AND условиях 1 https://wiki.postgresql.org/wiki/Index-only_scans
  • 35. 35 Как ускорить запрос? Методы соединения данных • nested loop - оптимален для небольших наборов данных • hash join - оптимален для больших наборов данных • merge join - оптимален для больших наборов данных, в случае, если они отсортированы
  • 36. 36 Как ускорить запрос? Какие бывают индексы? • partial create index concurrently ... on post using btree(domain_id, created) where pinned = true; • multicolumn create index concurrently ... on events using btree(user_id, type); • functional create index concurrently ... on i_movement using btree((coalesce(m_movement_id, 0))); • btree/gin/gist/brin
  • 37. 37 Система • Linux: Debian/Ubuntu/CentOS/RHEL • в kernel 3.2 есть некоторые проблемы с IO2 • I/O scheduler: noop, deadline, cfq • ionice/renice background процессам 2 http://www.databasesoup.com/2014/09/why-you-need-to-avoid-linux-kernel-32.html
  • 38. 38 Система sysctl.conf • по-умолчанию vm.dirty_ratio = 20, vm.dirty_background_ratio = 10 • vm.dirty_bytes • vm.dirty_background_bytes • vm.swappiness = 1 (swap лучше иметь, но он не должен использоваться)
  • 39. 39 Файловая система • ext4/xfs • noatime • barrier=0 (при наличии raid контроллера с "батарейкой")
  • 40. 40 Диски • SSD (server grade!) • SAS 15k • SATA
  • 41. 41 RAID • RAID 10 • контроллер с "батарейкой"(BBU) • cache mode write back
  • 42. 42 RAM • В один сервер можно поставить сравнительно много 128GB-256GB-... • Хорошо, когда активно используемая часть базы помещается в память • Для больших объемов имеет смысл включить huge pages (9.2, 9.4+)3 3 https://habrahabr.ru/post/228793/
  • 43. 43 CPU • Обычно не является лимитирующим фактором, но не всегда • Для многопроцессорных систем следует выключать NUMA4: • numa → off (node interleaving → enabled) в BIOS • или vm.zone_reclaim_mode = 0 в sysctl.conf 4 http://frosty-postgres.blogspot.ru/2012/08/postgresql-numa-and-zone-reclaim-mode.html
  • 44. 44 Заключение • Нужны метрики производительности системы • Потенциальных узких мест в системе может быть много • Возможности по обработке данных у SQL запросов очень большие • Для поиска проблемных запросов парсим логи или используем pg_stat_statements • Для оптимизации запросов нужно уметь читать вывод explain • К выбору железа нужно подходить с умом
  • 45. 45 Полезные ссылки • Different Approaches for MVCC used in well known Databases • depesz: Explaining the unexplainable • Объясняя необъяснимое • https://github.com/PostgreSQL-Consulting/pg-utils • http://blog.postgresql-consulting.com/