web-dev-qa-db-fra.com

Une même requête PostgreSQL peut-elle utiliser plusieurs cœurs?

Dans les versions récentes de PostgreSQL (depuis décembre 2013), pouvons-nous partager une requête entre deux ou plusieurs cœurs pour obtenir une amélioration des performances? Ou devrions-nous obtenir des cœurs plus rapides?

60
ALH

Non, pour les versions de PostgreSQL antérieures à la v9.6. Veuillez consulter la FAQ PostgreSQL : Comment PostgreSQL utilise-t-il les ressources CPU?

Le serveur PostgreSQL est basé sur les processus (non threadé). Chaque session de base de données se connecte à un unique processus du système d'exploitation (OS) PostgreSQL . Plusieurs sessions sont automatiquement réparties sur tous les processeurs disponibles par le système d'exploitation. Le système d'exploitation utilise également des processeurs pour gérer les E/S disque et exécuter d'autres tâches non liées à la base de données. Les applications clientes peuvent utiliser des threads, dont chacun se connecte à un processus de base de données distinct.

Depuis la version 9.6, des portions de certaines requêtes peuvent être exécutées en parallèle, dans des processus OS séparés, permettant l'utilisation de plusieurs cœurs de processeur. Les requêtes parallèles sont activées par défaut dans la version 10 (max_parallel_workers_per_gather), avec un parallélisme supplémentaire attendu dans les futures versions.

52
Jayadevan

PostgreSQL 9.6 + à partir de ce moment, commencerait à voir Parallel-Query arriver enfin à PostgreSQL.

Par exemple Des concepts comme Parallel Scan / Parallel Join / Parallel Aggregates sont maintenant déjà intégrés, et d'autres seront bientôt disponibles.

Ce qui est vraiment excitant, c'est qu'il y a rapports confirmant near-linear speed-up dans certains cas, ce qui est assez impressionnant!

38
Robins Tharakan

Non, mais il existe une solution de contournement. :)

J'ai trouvé la fonction plpgsql de parsel (sélection parallèle), qui divise votre requête en fonction de la clé primaire, puis se connecte à la base de données via l'extension dblink et attend toutes les sous-requêtes.

https://Gist.github.com/mjgleaso/8031067

L'auteur a également écrit un article sur cette fonction: http://geeohspatial.blogspot.com/2013/12/a-simple-function-for-parallel-queries_18.html

8
Evgen Bodunov

Non. Chaque connexion génère un processus distinct sur le serveur.

Vous pouvez "émuler" un certain parallélisme en utilisant un langage procédural fileté comme pljava. Créez une Java procédure (fonction) qui lance plusieurs threads et crée le résultat de sortie à l'aide de plusieurs travailleurs. Le backend est synchronisé afin que chaque travailleur puisse mettre à jour la sortie de manière asynchrone.

Java a un bon support pour la coordination/coopération des threads.

Par exemple, ce serait bien pour les opérations gourmandes en CPU ou les opérations de longueur de réseau.

3
cavila