Il peut y avoir différents types de traitement par lots impliqués, et j'en couvrirais une partie du pilote PostgreSQL JDBC (pgjdbc).
TL; DR :pgjdbc utilise moins d'allers-retours réseau dans le cas où l'API batch est utilisée. BatchedQuery
est utilisé uniquement si reWriteBatchedInserts=true
est transmis aux paramètres de connexion pgjdbc.
Vous pourriez trouver https://www.slideshare.net/VladimirSitnikv/postgresql-and-jdbc-striving-for-high-performance pertinent (diapositive 44,...)
En ce qui concerne l'exécution des requêtes, la latence du réseau représente souvent une part importante du temps écoulé.
Supposons que le cas consiste à insérer 10 lignes.
-
Pas de traitement par lot (par exemple, juste
PreparedStatement#execute
en boucle). Le conducteur effectuerait ce qui suitexecute query sync <-- wait for the response from the DB execute query sync <-- wait for the response from the DB execute query sync <-- wait for the response from the DB ...
Un temps notable serait passé dans "l'attente de la BD"
-
API batch JDBC. C'est
PreparedStatement#addBatch()
permet au pilote d'envoyer plusieurs "exécutions de requêtes" dans un seul aller-retour réseau. La mise en œuvre actuelle, cependant, diviserait toujours les gros lots en plus petits pour éviter les blocages TCP.Les actions seraient bien meilleures :
execute query ... execute query execute query execute query sync <-- wait for the response from the DB
-
Notez que même avec
#addBatch
, il y a une surcharge des commandes "exécuter la requête". Cela prend un temps considérable au serveur pour traiter chaque message individuellement.L'un des moyens de réduire le nombre de requêtes consiste à utiliser l'insertion multi-valeurs. Par exemple :
insert into tab(a,b,c) values (?,?,?), (?,?,?), ..., (?,?,?)
Ce PostgreSQL permet d'insérer plusieurs lignes à la fois. L'inconvénient est que vous n'avez pas de message d'erreur détaillé (par ligne). Actuellement, Hibernate n'implémente pas l'insertion multi-valeurs.
Cependant, pgjdbc peut réécrire à la volée les insertions de lots régulières en multi-valeurs depuis 9.4.1209 (2016-07-15).
Afin d'activer la réécriture multi-valeurs, vous devez ajouter
reWriteBatchedInserts=true
propriété de connexion. La fonctionnalité a été initialement développée dans https://github.com/pgjdbc/pgjdbc/pull/491Il est assez intelligent d'utiliser 2 instructions pour insérer 10 lignes. Le premier est un énoncé à 8 valeurs et le second est un énoncé à 2 valeurs. L'utilisation de puissances de deux permet à pgjdbc de conserver le nombre d'instructions distinctes, ce qui améliore les performances car les instructions souvent utilisées sont préparées par le serveur (voir Quelle est la durée de vie d'une instruction préparée côté serveur PostgreSQL )
BatchedQuery
représente ce type d'instructions à plusieurs valeurs, vous verrez donc cette classe utilisée dansreWriteBatchedInserts=true
cas uniquement.Les inconvénients de la fonctionnalité peuvent inclure :des détails inférieurs au "résultat du lot". Par exemple, un lot régulier vous donne "par nombre de lignes d'instruction", mais dans le cas de plusieurs valeurs, vous obtenez simplement le statut "instruction terminée". En plus de cela, la réécriture à la volée peut ne pas réussir à analyser certaines instructions SQL (par exemple, https://github.com/pgjdbc/pgjdbc/issues/1045 ).