PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Je vous suggĂšre de lire la transcription du rapport de Vladimir Sitnikov dĂ©but 2016 « PostgreSQL et JDBC extraient tout le jus Â»

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Bon aprÚs-midi Je m'appelle Vladimir Sitnikov. Je travaille pour NetCracker depuis 10 ans. Et je suis surtout intéressé par la productivité. Tout ce qui touche à Java, tout ce qui touche à SQL, c'est ce que j'aime.

Et aujourd'hui, je vais parler de ce que nous avons rencontrĂ© dans l'entreprise lorsque nous avons commencĂ© Ă  utiliser PostgreSQL comme serveur de base de donnĂ©es. Et nous travaillons principalement avec Java. Mais ce que je vais vous dire aujourd’hui ne concerne pas seulement Java. Comme l'a montrĂ© la pratique, cela se produit Ă©galement dans d'autres langues.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Nous parlerons:

  • sur l'Ă©chantillonnage des donnĂ©es.
  • À propos de la sauvegarde des donnĂ©es.
  • Et aussi sur les performances.
  • Et Ă  propos des rĂąteaux sous-marins qui y sont enterrĂ©s.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Commençons par une question simple. Nous sélectionnons une ligne du tableau en fonction de la clé primaire.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

La base de donnĂ©es est situĂ©e sur le mĂȘme hĂŽte. Et tout ce farm prend 20 millisecondes.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Ces 20 millisecondes, c'est beaucoup. Si vous avez 100 requĂȘtes de ce type, alors vous passez du temps par seconde Ă  faire dĂ©filer ces requĂȘtes, c'est-Ă -dire nous perdons du temps.

Nous n’aimons pas faire ça et regardons ce que la base nous propose pour cela. La base de donnĂ©es nous offre deux options pour exĂ©cuter des requĂȘtes.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

La premiùre option est une simple demande. Qu'est-ce qu'il y a de bien là-dedans ? Le fait que nous le prenons et l’envoyons, et rien de plus.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/478

La base de donnĂ©es dispose Ă©galement d'une requĂȘte avancĂ©e, plus dĂ©licate, mais plus fonctionnelle. Vous pouvez envoyer sĂ©parĂ©ment une demande d'analyse, d'exĂ©cution, de liaison de variable, etc.

La requĂȘte super Ă©tendue est quelque chose que nous ne couvrirons pas dans le rapport actuel. Nous voulons peut-ĂȘtre quelque chose de la base de donnĂ©es et il y a une liste de souhaits qui a Ă©tĂ© formĂ©e sous une forme ou une autre, c'est-Ă -dire c'est ce que nous voulons, mais c'est impossible maintenant et l'annĂ©e prochaine. Alors on vient de l’enregistrer et on va faire tourner les principaux personnages.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Et ce que nous pouvons faire, c'est une requĂȘte simple et une requĂȘte Ă©tendue.

Quelle est la particularité de chaque approche ?

Une requĂȘte simple convient pour une exĂ©cution unique. Une fois fait et oubliĂ©. Et le problĂšme est qu’il ne prend pas en charge le format de donnĂ©es binaire, c’est-Ă -dire qu’il ne convient pas Ă  certains systĂšmes hautes performances.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

RequĂȘte Ă©tendue – vous permet de gagner du temps sur l'analyse. C'est ce que nous avons fait et avons commencĂ© Ă  utiliser. Cela nous a vraiment, vraiment aidĂ©. Il n'y a pas que des Ă©conomies sur l'analyse. Il y a des Ă©conomies sur le transfert de donnĂ©es. Le transfert de donnĂ©es au format binaire est beaucoup plus efficace.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Passons Ă  la pratique. VoilĂ  Ă  quoi ressemble une application typique. Cela pourrait ĂȘtre Java, etc.

Nous avons créé une dĂ©claration. ExĂ©cutĂ© la commande. Créé Ă  proximitĂ©. OĂč est l'erreur ici ? Quel est le problĂšme? Aucun problĂšme. C'est ce qui est dit dans tous les livres. C’est ainsi qu’il faut l’écrire. Si vous voulez des performances maximales, Ă©crivez comme ceci.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Mais la pratique a montrĂ© que cela ne fonctionne pas. Pourquoi? Parce que nous avons une mĂ©thode « proche ». Et lorsque nous faisons cela, du point de vue de la base de donnĂ©es, il s’avĂšre que c’est comme un fumeur travaillant avec une base de donnĂ©es. Nous avons dit "PARSE EXECUTE DEALLOCATE".

Pourquoi toute cette crĂ©ation et ce dĂ©chargement supplĂ©mentaires d'instructions ? Personne n’en a besoin. Mais ce qui se passe gĂ©nĂ©ralement dans PreparedStatements, c'est que lorsque nous les fermons, ils ferment tout ce qui se trouve dans la base de donnĂ©es. Ce n'est pas ce que nous voulons.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Nous voulons, comme les personnes en bonne santĂ©, travailler avec la base. Nous avons pris et prĂ©parĂ© notre dĂ©claration une fois, puis nous l'avons exĂ©cutĂ©e plusieurs fois. En fait, plusieurs fois - c'est une fois dans toute la vie des applications - elles ont Ă©tĂ© analysĂ©es. Et nous utilisons le mĂȘme identifiant d'instruction sur diffĂ©rents REST. C'est notre objectif.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Comment pouvons-nous y parvenir?

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

C'est trĂšs simple : pas besoin de fermer les instructions. Nous l'Ă©crivons ainsi : « prĂ©parer Â» « exĂ©cuter Â».

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Si nous lançons quelque chose comme ça, alors il est clair que quelque chose va dĂ©border quelque part. Si ce n'est pas clair, vous pouvez l'essayer. Écrivons un benchmark qui utilise cette mĂ©thode simple. CrĂ©ez une dĂ©claration. Nous le lançons sur une version du pilote et constatons qu'il plante assez rapidement avec la perte de toute la mĂ©moire dont il disposait.

Il est clair que de telles erreurs sont faciles Ă  corriger. Je n'en parlerai pas. Mais je dirai que la nouvelle version fonctionne beaucoup plus rapidement. La mĂ©thode est stupide, mais quand mĂȘme.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Comment travailler correctement ? Que devons-nous faire pour cela ?

En réalité, les applications ferment toujours les instructions. Dans tous les livres, ils disent de le fermer, sinon la mémoire fuira.

Et PostgreSQL ne sait pas comment mettre en cache les requĂȘtes. Il faut que chaque session crĂ©e ce cache pour elle-mĂȘme.

Et nous ne voulons pas non plus perdre de temps en analyse.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Et comme d'habitude, nous avons deux options.

La premiĂšre option est de prendre cela et de dire que nous enveloppons tout dans PgSQL. Il y a une cache lĂ -bas. Il met tout en cache. Cela s'avĂ©rera gĂ©nial. Nous avons vu cela. Nous avons 100500 XNUMX demandes. Ne marche pas. Nous n’acceptons pas de transformer manuellement les demandes en procĂ©dures. Non non.

Nous avons une deuxiĂšme option : prenez-le et coupez-le nous-mĂȘmes. Nous ouvrons les sources et commençons Ă  couper. Nous avons vu et vu. Il s'est avĂ©rĂ© que ce n'est pas si difficile Ă  faire.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/319

Celui-ci est apparu en aoĂ»t 2015. Il existe dĂ©sormais une version plus moderne. Et tout est gĂ©nial. Cela fonctionne tellement bien qu’on ne change rien dans l’application. Et nous avons mĂȘme arrĂȘtĂ© de penser en direction de PgSQL, c'est-Ă -dire cela nous suffisait amplement pour rĂ©duire tous les frais gĂ©nĂ©raux Ă  presque zĂ©ro.

En consĂ©quence, les instructions prĂ©parĂ©es par le serveur sont activĂ©es Ă  la 5Ăšme exĂ©cution afin d'Ă©viter de gaspiller de la mĂ©moire dans la base de donnĂ©es Ă  chaque requĂȘte unique.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Vous vous demandez peut-ĂȘtre : oĂč sont les chiffres ? Qu'obtenez-vous ? Et ici je ne donnerai pas de chiffres, car chaque demande a le sien.

Nos requĂȘtes Ă©taient telles que nous avons passĂ© environ 20 millisecondes Ă  analyser les requĂȘtes OLTP. Il y avait 0,5 millisecondes pour l'exĂ©cution, 20 millisecondes pour l'analyse. RequĂȘte – 10 Ko de texte, 170 lignes de plan. Il s'agit d'une requĂȘte OLTP. Il demande 1, 5, 10 lignes, parfois plus.

Mais nous ne voulions pas du tout perdre 20 millisecondes. Nous l'avons réduit à 0. Tout est trÚs bien.

Que pouvez-vous retenir d’ici ? Si vous avez Java, prenez la version moderne du pilote et rĂ©jouissez-vous.

Si vous parlez une langue diffĂ©rente, rĂ©flĂ©chissez : peut-ĂȘtre en avez-vous aussi besoin ? Car du point de vue du langage final, par exemple, si PL 8 ou si vous avez LibPQ, alors il n'est pas Ă©vident pour vous que vous perdiez du temps non pas sur l'exĂ©cution, sur l'analyse, et cela mĂ©rite d'ĂȘtre vĂ©rifiĂ©. Comment? Tout est gratuit.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Sauf qu’il y a des erreurs et quelques particularitĂ©s. Et nous en parlerons maintenant. La majeure partie portera sur l'archĂ©ologie industrielle, sur ce que nous avons trouvĂ©, sur ce que nous avons dĂ©couvert.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Si la demande est gĂ©nĂ©rĂ©e dynamiquement. Ça arrive. Quelqu'un colle les chaĂźnes ensemble, ce qui gĂ©nĂšre une requĂȘte SQL.

Pourquoi est-il mauvais ? C'est dommage car à chaque fois on se retrouve avec une chaßne différente.

Et le hashCode de cette chaĂźne diffĂ©rente doit ĂȘtre relu. Il s'agit en rĂ©alitĂ© d'une tĂąche du processeur : trouver un long texte de requĂȘte, mĂȘme dans un hachage existant, n'est pas si simple. Par consĂ©quent, la conclusion est simple : ne gĂ©nĂ©rez pas de demandes. Stockez-les dans une variable. Et rĂ©jouissez-vous.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Prochain problĂšme. Les types de donnĂ©es sont importants. Il existe des ORM qui disent que peu importe le type de NULL existant, qu'il y en ait un. Si Int, alors nous disons setInt. Et si NULL, alors que ce soit toujours VARCHAR. Et quelle diffĂ©rence cela fait-il au final, qu'y ait-il NULL ? La base de donnĂ©es elle-mĂȘme comprendra tout. Et cette image ne fonctionne pas.

En pratique, la base de données s'en fiche du tout. Si vous avez dit la premiÚre fois qu'il s'agit d'un nombre, et la deuxiÚme fois que vous avez dit qu'il s'agit d'un VARCHAR, alors il est impossible de réutiliser les instructions préparées par le serveur. Et dans ce cas, nous devons recréer notre déclaration.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Si vous exĂ©cutez la mĂȘme requĂȘte, assurez-vous que les types de donnĂ©es de votre colonne ne sont pas confondus. Vous devez faire attention Ă  NULL. Il s'agit d'une erreur courante que nous avons rencontrĂ©e aprĂšs avoir commencĂ© Ă  utiliser PreparedStatements.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

D'accord, allumĂ©. Peut-ĂȘtre qu'ils ont pris le chauffeur. Et la productivitĂ© a chutĂ©. Les choses ont mal tournĂ©.

Comment cela peut-il arriver? Est-ce un bug ou une fonctionnalitĂ©? Malheureusement, il n'a pas Ă©tĂ© possible de comprendre s'il s'agissait d'un bug ou d'une fonctionnalitĂ©. Mais il existe un scĂ©nario trĂšs simple pour reproduire ce problĂšme. Elle nous a tendu une embuscade de maniĂšre complĂštement inattendue. Et cela consiste Ă  Ă©chantillonner littĂ©ralement Ă  partir d’une seule table. Bien entendu, nous avons eu davantage de demandes de ce type. En rĂšgle gĂ©nĂ©rale, ils comprenaient deux ou trois tables, mais il existe un tel scĂ©nario de lecture. Prenez n’importe quelle version de votre base de donnĂ©es et jouez-la.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Le fait est que nous avons deux colonnes, chacune étant indexée. Il y a un million de lignes dans une colonne NULL. Et la deuxiÚme colonne ne contient que 20 lignes. Lorsque nous exécutons sans variables liées, tout fonctionne bien.

Si nous commençons Ă  exĂ©cuter avec des variables liĂ©es, c'est-Ă -dire que nous exĂ©cutons le "?" ou « 1 $ Â» pour notre demande, qu'obtenons-nous finalement ?

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

La premiĂšre exĂ©cution est comme prĂ©vu. Le second est un peu plus rapide. Quelque chose a Ă©tĂ© mis en cache. TroisiĂšme, quatriĂšme, cinquiĂšme. Puis bang - et quelque chose comme ça. Et le pire, c'est que cela se produit Ă  la sixiĂšme exĂ©cution. Qui savait qu’il Ă©tait nĂ©cessaire de procĂ©der exactement Ă  six exĂ©cutions pour comprendre quel Ă©tait le vĂ©ritable plan d’exĂ©cution ?

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Qui est coupable ? Ce qui s'est passĂ©? La base de donnĂ©es contient une optimisation. Et il semble optimisĂ© pour le cas gĂ©nĂ©rique. Et, en consĂ©quence, Ă  partir d’un moment donnĂ©, elle passe Ă  un plan gĂ©nĂ©rique, qui, malheureusement, peut s’avĂ©rer diffĂ©rent. Cela peut s'avĂ©rer ĂȘtre le mĂȘme, ou cela peut ĂȘtre diffĂ©rent. Et il existe une sorte de valeur seuil qui conduit Ă  ce comportement.

Que peux-tu y faire? Ici, bien entendu, il est plus difficile de présumer quoi que ce soit. Il existe une solution simple que nous utilisons. C'est +0, OFFSET 0. Vous connaissez sûrement de telles solutions. Nous le prenons simplement et ajoutons « +0 » à la demande et tout va bien. Je te montrerai plus tard.

Et il existe une autre option : examinez les plans plus attentivement. Le développeur doit non seulement rédiger une demande, mais aussi dire « expliquer analyser » 6 fois. Si c'est 5, ça ne marchera pas.

Et il existe une troisiÚme option : écrire une lettre aux pirates de pgsql. J'ai écrit, cependant, il n'est pas encore clair s'il s'agit d'un bug ou d'une fonctionnalité.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://gist.github.com/vlsi/df08cbef370b2e86a5c1

Pendant que nous nous demandons s’il s’agit d’un bug ou d’une fonctionnalitĂ©, corrigeons-le. Prenons notre demande et ajoutons "+0". Tout va bien. Deux symboles et vous n’avez mĂȘme pas besoin de penser Ă  ce que c’est ou Ă  ce que c’est. TrĂšs simple. Nous avons simplement interdit Ă  la base de donnĂ©es d'utiliser un index sur cette colonne. Nous n’avons pas d’index sur la colonne « +0 » et c’est tout, la base de donnĂ©es n’utilise pas l’index, tout va bien.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

C'est la rĂšgle de 6, expliquez-vous. DĂ©sormais, dans les versions actuelles, vous devez le faire 6 fois si vous avez des variables liĂ©es. Si vous n'avez pas de variables liĂ©es, c'est ce que nous faisons. Et finalement, c’est prĂ©cisĂ©ment cette demande qui Ă©choue. Ce n'est pas une chose dĂ©licate.

Il semblerait, combien est-il possible ? Un bug ici, un bug lĂ . En fait, le bug est partout.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Regardons de plus prĂšs. Par exemple, nous avons deux schĂ©mas. SchĂ©ma A avec tableau S et schĂ©ma B avec tableau S. RequĂȘte – sĂ©lectionnez des donnĂ©es dans une table. Qu'aurons-nous dans ce cas ? Nous aurons une erreur. Nous aurons tout ce qui prĂ©cĂšde. La rĂšgle est la suivante : un bug est partout, nous aurons tout ce qui prĂ©cĂšde.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Maintenant la question est : « Pourquoi ? » Il semblerait qu'il existe une documentation selon laquelle si nous avons un schĂ©ma, alors il existe une variable "search_path" qui nous indique oĂč chercher la table. Il semblerait qu'il existe une variable.

Quel est le problĂšme? Le problĂšme est que les instructions prĂ©parĂ©es par le serveur ne soupçonnent pas que search_path peut ĂȘtre modifiĂ© par quelqu'un. Cette valeur reste en quelque sorte constante pour la base de donnĂ©es. Et certaines parties peuvent ne pas acquĂ©rir de nouvelles significations.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Bien entendu, cela dĂ©pend de la version sur laquelle vous testez. Cela dĂ©pend de la gravitĂ© de la diffĂ©rence entre vos tables. Et la version 9.1 exĂ©cutera simplement les anciennes requĂȘtes. Les nouvelles versions peuvent dĂ©tecter le bug et vous informer que vous avez un bug.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Définir search_path + instructions préparées par le serveur =
le plan mis en cache ne doit pas changer le type de résultat

Comment le traiter ? Il existe une recette simple : ne la faites pas. Il n'est pas nécessaire de modifier search_path pendant l'exécution de l'application. Si vous changez, il est préférable de créer une nouvelle connexion.

Vous pouvez discuter, c'est-Ă -dire ouvrir, discuter, ajouter. Peut-ĂȘtre pouvons-nous convaincre les dĂ©veloppeurs de bases de donnĂ©es que lorsque quelqu'un modifie une valeur, la base de donnĂ©es devrait en informer le client : « Écoutez, votre valeur a Ă©tĂ© mise Ă  jour ici. Peut-ĂȘtre avez-vous besoin de rĂ©initialiser les dĂ©clarations et de les recrĂ©er ? Â» DĂ©sormais, la base de donnĂ©es se comporte secrĂštement et ne signale en aucune maniĂšre que les instructions ont changĂ© quelque part Ă  l'intĂ©rieur.

Et j'insiste encore une fois : c'est quelque chose qui n'est pas typique de Java. Nous verrons la mĂȘme chose en PL/pgSQL un Ă  un. Mais il y sera reproduit.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Essayons une sélection supplémentaire de données. Nous choisissons et choisissons. Nous avons une table avec un million de lignes. Chaque ligne fait un kilo-octet. Environ un gigaoctet de données. Et nous avons une mémoire de travail dans la machine Java de 128 mégaoctets.

Comme recommandĂ© dans tous les livres, nous utilisons le traitement de flux. Autrement dit, nous ouvrons resultSet et lisons les donnĂ©es Ă  partir de lĂ  petit Ă  petit. Est-ce que ça marchera? Est-ce que cela tombera de la mĂ©moire ? Veux-tu lire un peu ? Faisons confiance Ă  la base de donnĂ©es, faisons confiance Ă  Postgres. Nous n'y croyons pas. Allons-nous tomber en OutOFMemory ? Qui a connu OutOfMemory ? Qui a rĂ©ussi Ă  le rĂ©parer aprĂšs ça ? Quelqu'un a rĂ©ussi Ă  le rĂ©parer.

Si vous avez un million de lignes, vous ne pouvez pas simplement choisir. OFFSET/LIMIT est requis. Qui est pour cette option ? Et qui est favorable Ă  jouer avec autoCommit ?

Ici, comme d'habitude, l'option la plus inattendue s'avĂšre correcte. Et si vous dĂ©sactivez soudainement autoCommit, cela vous aidera. Pourquoi donc? La science n’en sait rien.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Mais par dĂ©faut, tous les clients se connectant Ă  une base de donnĂ©es Postgres rĂ©cupĂšrent l'intĂ©gralitĂ© des donnĂ©es. PgJDBC ne fait pas exception Ă  cet Ă©gard : il sĂ©lectionne toutes les lignes.

Il existe une variante du thÚme FetchSize, c'est-à-dire que vous pouvez dire au niveau d'une instruction distincte qu'ici, veuillez sélectionner les données par 10, 50. Mais cela ne fonctionne pas tant que vous n'avez pas désactivé autoCommit. AutoCommit désactivé - il commence à fonctionner.

Mais parcourir le code et définir setFetchSize partout n'est pas pratique. Par conséquent, nous avons défini un paramÚtre qui indiquera la valeur par défaut pour l'ensemble de la connexion.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

C'est ce que nous avons dit. Le paramĂštre a Ă©tĂ© configurĂ©. Et qu’avons-nous obtenu ? Si nous sĂ©lectionnons de petits montants, si, par exemple, nous sĂ©lectionnons 10 lignes Ă  la fois, nous avons alors des frais gĂ©nĂ©raux trĂšs importants. Par consĂ©quent, cette valeur doit ĂȘtre fixĂ©e Ă  environ une centaine.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Idéalement, bien sûr, vous devez encore apprendre à le limiter en octets, mais la recette est la suivante : définissez defaultRowFetchSize sur plus de cent et soyez heureux.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Passons Ă  l'insertion de donnĂ©es. L'insertion est plus facile, il existe diffĂ©rentes options. Par exemple, INSÉRER, VALEURS. C'est une bonne option. Vous pouvez dire « INSERT SELECT ». En pratique, c'est la mĂȘme chose. Il n'y a aucune diffĂ©rence de performances.

Les livres disent que vous devez exécuter une instruction Batch, les livres disent que vous pouvez exécuter des commandes plus complexes avec plusieurs parenthÚses. Et Postgres a une fonctionnalité merveilleuse : vous pouvez faire COPY, c'est-à-dire le faire plus rapidement.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Si vous le mesurez, vous pourrez à nouveau faire des découvertes intéressantes. Comment voulons-nous que cela fonctionne ? Nous ne voulons pas analyser ni exécuter de commandes inutiles.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

En pratique, TCP ne nous permet pas de faire cela. Si le client est occupĂ© Ă  envoyer une requĂȘte, la base de donnĂ©es ne lit pas les requĂȘtes pour tenter de nous envoyer des rĂ©ponses. Le rĂ©sultat final est que le client attend que la base de donnĂ©es lise la demande et que la base de donnĂ©es attend que le client lise la rĂ©ponse.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Et donc le client est obligé d'envoyer périodiquement un paquet de synchronisation. Interactions réseau supplémentaires, perte de temps supplémentaire.

PostgreSQL et JDBC en extraient tout le jus. Vladimir SitnikovEt plus on en ajoute, plus la situation empire. Le conducteur est assez pessimiste et les ajoute assez souvent, environ une fois toutes les 200 lignes, selon la taille des lignes, etc.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

https://github.com/pgjdbc/pgjdbc/pull/380

Il arrive que vous corrigiez une seule ligne et que tout s'accĂ©lĂšre 10 fois. Ça arrive. Pourquoi? Comme d'habitude, une constante comme celle-ci a dĂ©jĂ  Ă©tĂ© utilisĂ©e quelque part. Et la valeur « 128 Â» signifiait ne pas utiliser le traitement par lots.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Harnais de microbenchmark Java

C'est bien que cela ne soit pas inclus dans la version officielle. Découvert avant le début de la sortie. Toutes les significations que je donne sont basées sur des versions modernes.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Essayons-le. Nous mesurons InsertBatch simple. Nous mesurons InsertBatch plusieurs fois, c'est-Ă -dire la mĂȘme chose, mais il existe de nombreuses valeurs. DĂ©placement dĂ©licat. Tout le monde ne peut pas faire cela, mais c’est une dĂ©marche si simple, bien plus facile que COPIER.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Vous pouvez faire COPIER.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Et vous pouvez le faire sur des structures. Déclarez le type par défaut de l'utilisateur, transmettez le tableau et INSERT directement dans la table.

Si vous ouvrez le lien : pgjdbc/ubenchmsrk/InsertBatch.java, alors ce code est sur GitHub. Vous pouvez voir spécifiquement quelles demandes y sont générées. Cela n'a pas d'importance.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Nous avons lancĂ©. Et la premiĂšre chose que nous avons rĂ©alisĂ©, c’est que ne pas utiliser le batch est tout simplement impossible. Toutes les options de batching sont nulles, c'est-Ă -dire que le temps d'exĂ©cution est pratiquement nul par rapport Ă  une exĂ©cution unique.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Nous insérons des données. C'est un tableau trÚs simple. Trois colonnes. Et que voit-on ici ? Nous constatons que ces trois options sont à peu prÚs comparables. Et COPIER est, bien sûr, meilleur.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

C'est Ă  ce moment-lĂ  que nous insĂ©rons des piĂšces. Quand nous avons dit qu'une valeur VALEURS, deux valeurs VALEURS, trois valeurs VALEURS, ou nous en avons indiquĂ© 10 sĂ©parĂ©es par une virgule. C'est juste horizontal maintenant. 1, 2, 4, 128. On peut voir que l'encart de lot, dessinĂ© en bleu, lui permet de se sentir beaucoup mieux. Autrement dit, lorsque vous en insĂ©rez un Ă  la fois ou mĂȘme lorsque vous en insĂ©rez quatre Ă  la fois, cela devient deux fois mieux, simplement parce que nous avons mis un peu plus de VALEURS. Moins d’opĂ©rations EXECUTE.

Utiliser COPY sur de petits volumes est extrĂȘmement peu prometteur. Je n'ai mĂȘme pas dessinĂ© les deux premiers. Ils vont au paradis, c'est-Ă -dire ces nombres verts pour COPIER.

COPY doit ĂȘtre utilisĂ© lorsque vous disposez d'au moins une centaine de lignes de donnĂ©es. La surcharge liĂ©e Ă  l’ouverture de cette connexion est importante. Et pour ĂȘtre honnĂȘte, je n’ai pas creusĂ© dans cette direction. J'ai optimisĂ© Batch, mais pas COPY.

Que faisons-nous ensuite? Nous l'avons essayé. Nous comprenons qu'il faut utiliser soit des structures, soit un bain astucieux qui combine plusieurs significations.

PostgreSQL et JDBC en extraient tout le jus. Vladimir Sitnikov

Que devriez-vous retenir du rapport d’aujourd’hui ?

  • PreparedStatement est notre tout. Cela donne beaucoup pour la productivitĂ©. Cela produit un gros Ă©chec dans la pommade.
  • Et vous devez faire EXPLIQUER ANALYSER 6 fois.
  • Et nous devons diluer OFFSET 0 et des astuces comme +0 afin de corriger le pourcentage restant de nos requĂȘtes problĂ©matiques.

Source: habr.com

Achetez un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Achetez un hĂ©bergement web fiable avec protection DDoS, serveurs VPS et VDS | ProHoster