В предыдущих статьях я писал о получении параллельного sequential scan закоммиченного в PostgreSQL 9.5. Но этого не случилось. Однако, я с удовольствием расскажу вам о первом коммите parallel sequential scan в PostgreSQL в master ветку с целью предстоящего релиза PostgreSQL 9.6.
Параллельные запросы для PostgreSQL были долгое время моей мечтой, над которыми я работал несколько лет. Их разработка их началась c PostgreSQL 9.4 релизном цикле, где я добавил динамические воркеры, работающие в фоне и динамическую shared memory, разработка которой продолжилась в PostgreSQL 9.5, где имела место идея в добавлении фундаментальной инфраструктуры для параллелизма которая сегодня была закоммиченна. Я хотел бы рассказать вам немного о сегодняшних коммитах и о работе, которая будет проделана дальше.
Но первое, что я хотел бы сделать это поблагодарить тех, кого я должен. Во первых Amit Kapila, который внес громадный вклад в завершение проекта. Мы вдвоем написали большое количество кода, который стал полноценной частью этого функционала. И часть этого кода прошла через множество коммитов в течение последних нескольких лет. Так же мы написали большое количество кода, который не вошел в коммиты. Во-вторых, я хочу сказать спасибо Noah Misch, который хорошо помогал мне на ранних стадиях в этом проекте, когда я боролся с проблемами в поисках пути их решения. В-третьих, я хотел бы сказать спасибо PostgreSQL комьюнити и отдельным людям, которые поддерживали review и тестовые патчи, предложенные усовершенствования и многим другим, кто нас поддерживал разными способами.
Так же важно сказать спасибо EnterpriseDB, в частности, ее руководству. Во первых, Tom Kincaid и Marc Linster. Без их поддержки было бы не возможно нам с Ammit's посветить много времени этому проекту, а так же без моей команды в EnterpriseDB, которые терпеливо прикрывали меня всякий раз, когда нужно было решать другие рабочие вопросы. Спасибо всем.
Теперь, время для demo:
rhaas=# timing
Timing is on.
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 743.061 ms
rhaas=# set max_parallel_degree = 4;
SET
Time: 0.270 ms
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 213.412 ms
Вот как выглядит план:
rhaas=# explain (costs off) select * from pgbench_accounts where filler like '%a%';
QUERY PLAN
---------------------------------------------
Gather
Number of Workers: 4
-> Parallel Seq Scan on pgbench_accounts
Filter: (filler ~~ '%a%'::text)
(4 rows)
Накапливающий узел собирает все воркеры, и все воркеры запускаются в дополнительном плане параллельно. Потому что дополнительный план Parallel Seq Scan — обыкновенный Seq Scan. Воркеры координируются с друг другом так, что каждый блок в отношении сканируется только один раз. Каждый воркер может производить подмножество финальных result set, а собирающий узел собирает результаты со всех.
Одно достаточно больше ограничение текущей реализации является то, что мы генерируем сборщиков узлов на вершине Parallel Seq Scan узлов. Это означает, что эта функция в настоящее время не работает для иерархии наследования (с использованием разделенного партицирования таблиц), потому что её можно будет добавить между узлами. Так же не возможно протолкнуть join вниз в воркеры в настоящее время. Исполнитель инфраструктуры поддерживает запуск планов каждого типа, но текущий планировщик слишком глуп для поддержки этого. Я надеюсь исправить эту проблему до окончания релизного цикла 9.6. С учетом текущего положения вещей использование этой фичи будет давать преимущество там, где добавление индекса уже не помогает и добавление нескольких воркеров поможет увеличить скорость выполнения.
Так же мой опыт говорит, что добавления нескольких воркеров как правило помогает, и преимущество плохо масштабируются с большим количество воркеров. Так же необходимо более глубокое исследование, чтобы понять почему это происходит и как это улучшить… Как вы видите даже 5 воркеров могут повысить производительность совсем немного, но это не так важно как в предыдущем ограничении. Однако, я хотел бы совершенствовать их дальше, так как количество CPU растет все это время.
В завершении, я хотел бы отметить, что есть еще ряд определенных задач, которые должны быть закончены, прежде, чем я могу назвать эту функцию даже в базовой форме полностью законченной. Вероятно что еще остались ошибки. Тестирование очень высоко ценится. Пожалуйста, сообщите проблемы, которые вы найдете при тестировании на pgsql-hackers и postgresql.org. Спасибо.
Автор: itcoder