зеркало из
				https://github.com/iharh/notes.git
				synced 2025-10-30 21:26:09 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			46 строки
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			46 строки
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| *****************************************************************************
 | |
| Если у вас в PostgreSQL включено параллельное выполнение запросов, то планировщик, в целях повышения производительности выполнения запроса может решить использовать его. Что такое параллельное выполнение запросов, как работает и как его настроить будем разбираться в этой заметке.
 | |
| 
 | |
| Технически параллельное выполнение запросов происходит так: запрос разбивается на несколько частей и выполняется несколькими фоновыми процессами. Фоновые процессы общаются между собой через общий буфуер. Как только каждая часть запроса будет выполнена, его результат будет аккомулирован и передан ведущему процессу.
 | |
| 
 | |
| Результат команды EXPLAIN при параллельном выполнении запроса будет выглядеть примерно вот так:
 | |
| 
 | |
| Gather (cost=0.00..46010.00 rows=1000000 width=43)
 | |
| Workers Planned: 4
 | |
| Workers Launched: 4
 | |
| -> Parallel Seq Scan on my_table (cost=0.00..44010.00 rows=230000 width=43)
 | |
| 
 | |
| Вместо Gather еще может быть Gather Merge. В чем разница, разберемся дальше.
 | |
| 
 | |
| Здесь Gather показывает нам, что результат запроса был собран из нескольких параллельных процессов, Workers Planned - сколько параллельных процессов было запланировано к использованию планировщиком запросов, Workers Launched - сколько фактически параллельных процессов было использовано.
 | |
| 
 | |
| Разница между Gather и Gather Merge заключается в том, что Gather Merge участвует в операциях сортировки (ORDER BY), т.е. когда каждый из фоновых процессов производит сортировку своей части запроса и передает результат для финального слияния ведущему процессу. Gather используется в запросах без сортировки.
 | |
| 
 | |
| Есть несколько параметров в файле postgresql.conf, с помощью которых мы можем управлять параллельным выполнением запросов:
 | |
| 
 | |
| max_worker_processes - контролирует общее кол-во фоновых процессов, доступных всему кластеру PostgreSQL;
 | |
| 
 | |
| max_parallel_workers - контролирует общее кол-во активных процессов, доступных всему кластеру PostgreSQL для параллельного выполнения запросов. Значение этого параметра должно быть меньшим или равным значению параметра max_worker_processes;
 | |
| 
 | |
| max_parallel_workers_per_gather - значение этого параметра контролирует кол-во фоновых процессов, доступных для параллельного выполнения одного запроса.
 | |
| 
 | |
| Есть еще несколько параметров, с помощью которых мы можем контролировать стоимость выполнения параллельных запросов:
 | |
| 
 | |
| parallel_setup_cost - устанавливает стоимость запуска одного фонового процесса и выделения ему памяти. Значение по умолчанию 1000;
 | |
| 
 | |
| parallel_tuple_cost - устанавливает стоимость передачи данных между фоновыми процессами. Значение по умолчанию 0.1.
 | |
| 
 | |
| А еще мы можем управлять параллельным сканированием таблиц и индексов:
 | |
| 
 | |
| min_parallel_table_scan_size - устанавливает минимальный размер таблицы, при котором PostgreSQL примет решение о ее параллельном сканировании. Значение устанавливается в байтах, значение по умолчанию - 8MB. Т.е. параллельное сканирование не будет включаться на таблицах, объем которых меньше 8MB;
 | |
| 
 | |
| min_parallel_index_scan_size - тоже самое, что и предыдущий параметр, только для индексов. Значение по умолчанию 8MB.
 | |
| 
 | |
| А еще можно включить параметр force_parallel_mode (по умолчанию OFF) и тогда PostgreSQL будет пытаться параллелить все что возможно. Но на рабочем кластере лучше так не делать, так как могут быть неприятные нюансы.
 | |
| 
 | |
| Параллельное выполнение запросов наиболее эффективно при OLAP нагрузке, т.е. когда у вас в базе происходят долгие запросы для формирования какого-нибудь аналитического отчета. Когда у вас много коротких запросов, которые создают, обновляют или удаляют данные в базе, т.е. OLTP нагрузка, то толку от параллельного выполнения запросов будет мало, или не будет вообще. 
 | |
| 
 | |
| Для программ семейства 1с вообще рекомендуют отключать параллелизм, т.е. ставить параметр max_parallel_workers_per_gather в ноль, но тут все не так просто и настройки параллелизма могут зависеть от конкретной ситуации и типа нагрузки на базу данных.
 | |
| 
 | |
| О нюансах параллелизма запросов ещё расскажем в будущих постах 😉.
 | 
