0

Nouveautés pg_stat_statements avec PostgreSQL 15

twitterlinkedinmail

Salut à toutes et tous, aujourd’hui un petit post pour évoquer les quelques petites modifications apportées à pg_stat_statements, l’extension phare de PostgreSQL, et qui ont pu passer inaperçues depuis le 13 octobre, date de sortie de la dernière release majeure du SGBD aux grandes oreilles.

Si vous n’êtes pas familiers de pg_stat_statements je vous renvoie sur mon talk aux PGDays en 2021.

Si on regarde d’un peu plus près la documentation de référence, on va retrouver deux ajouts principaux:

Séparation des stats IO data & temporary

Tout d’abord en version 14, les colonnes blk_read_time et blk_write_time comptabilisaient les entrées / sorties vers tous les blocs, à la fois data et temporary. En version 15, deux nouvelles colonnes temp_blk_read_time et temp_blk_write_time sont ajoutées à la vue, pour séparer les deux types d’accès. Les anciennes colonnes ne font donc plus référence qu’aux accès aux blocs de data, et les 2 nouvelles qu’aux accès aux blocs temporary.

Infos sur les compilations JIT:

La deuxième différence qui est nettement plus visible, est l’ajout de toute la métrologie associée à la compilation Jit, introduite en 2018 pour la version 11 par Andres Freund, et qui permet d’accélérer l’exécution de code PL/PGSQL davantage en le compilant en langage natif à l’exécution, si le coût dépasse un seuil fixé par le paramètre jit_above_cost. Parmi ces nouvelles colonnes :

jit_functions           : Total number of functions JIT-compiled by the statement
jit_generation_time     : Total time spent by the statement on generating JIT code, in milliseconds
jit_inlining_count      : Number of times functions have been inlined
jit_inlining_time       : Total time spent by the statement on inlining functions, in milliseconds
jit_optimization_count  : Number of times the statement has been optimized
jit_optimization_time   : Total time spent by the statement on optimizing, in milliseconds
jit_emission_count      : Number of times code has been emitted
jit_emission_time       : Total time spent by the statement on emitting code, in milliseconds

Petit test pour voir avec une bonne grosse requête qui va nous faire un parallel seq scan et un hash aggregate en sortie, le tout sur 40 millions de lignes. Pour avoir un peu de volumétrie j’utilise la base de test de musicbrainz que je vous recommande:

(postgres@[local]:5432) [postgres] > select name, setting from pg_settings where name in ('jit','jit_above_cost') ;
      name      | setting 
----------------+---------
 jit            | on
 jit_above_cost | 100000
(2 rows)

(postgres@[local]:5432) [postgres] > \c musicbrainz
You are now connected to database "musicbrainz" as user "postgres".

(postgres@[local]:5432) [musicbrainz] > explain select name, count(id), avg(length) from track group by name having count(id) > 5 ;
                                            QUERY PLAN                                             
---------------------------------------------------------------------------------------------------
 Finalize GroupAggregate  (cost=2399394.22..2481941.16 rows=104483 width=60)
   Group Key: name
   Filter: (count(id) > 5)
   ->  Gather Merge  (cost=2399394.22..2472537.66 rows=626900 width=60)
         Workers Planned: 2
         ->  Sort  (cost=2398394.20..2399177.83 rows=313450 width=60)
               Sort Key: name
               ->  Partial HashAggregate  (cost=2124704.40..2357991.54 rows=313450 width=60)
                     Group Key: name
                     Planned Partitions: 16
                     ->  Parallel Seq Scan on track  (cost=0.00..741158.22 rows=16834022 width=28)
 JIT:
   Functions: 8
   Options: Inlining true, Optimization true, Expressions true, Deforming true
(14 rows)

OK on voit bien qu’avec notre cost final de +2399394 on est au dessus des 100K minimums nécessaire pour forcer le JIT. Exécutons la requête pour voir ce que l’on retrouve dans pg_stat_statements:

(postgres@[local]:5432) [musicbrainz] > select name, count(id), avg(length) from track group by name having count(id) > 5 ;
(...)
(746785 rows)
Time: 210439.640 ms (03:30.440)

(postgres@[local]:5432) [postgres] > \x
Expanded display is on.
(postgres@[local]:5432) [postgres] > select * from pg_stat_statements where query like 'select name, count(id), avg(length) from track%' ;
-[ RECORD 1 ]----------+-----------------------------------------------------------------------------------
userid                 | 10
dbid                   | 16388
toplevel               | t
queryid                | 6022129428306982548
query                  | select name, count(id), avg(length) from track group by name having count(id) > $1
plans                  | 0
total_plan_time        | 0
min_plan_time          | 0
max_plan_time          | 0
mean_plan_time         | 0
stddev_plan_time       | 0
calls                  | 1
total_exec_time        | 210435.894037
min_exec_time          | 210435.894037
max_exec_time          | 210435.894037
mean_exec_time         | 210435.894037
stddev_exec_time       | 0
rows                   | 746785
shared_blks_hit        | 16
shared_blks_read       | 572818
shared_blks_dirtied    | 0
shared_blks_written    | 0
local_blks_hit         | 0
local_blks_read        | 0
local_blks_dirtied     | 0
local_blks_written     | 0
temp_blks_read         | 1071638
temp_blks_written      | 1325851
blk_read_time          | 0
blk_write_time         | 0
temp_blk_read_time     | 0
temp_blk_write_time    | 0
wal_records            | 0
wal_fpi                | 0
wal_bytes              | 0
jit_functions          | 15
jit_generation_time    | 1.491564
jit_inlining_count     | 1
jit_inlining_time      | 237.918294
jit_optimization_count | 1
jit_optimization_time  | 360.290152
jit_emission_count     | 1
jit_emission_time      | 230.831919

Le cost étant à 2M+ on aura donc à la fois inlining et optimization car les 2 seuils jit_inline_above_cost et jit_optimize_above_cost sont à 500K, ce qui est confirmé par la sortie de PGSS ci-dessus.

Pour ce qui est de la version 16, qui devrait être ouverte en Beta d’ici un ou deux mois, pour l’instant pas d’ajout de nouvelle colonne à l’horizon.

Pensez à vous abonner à la page linkedin et à la chaîne youtube de Capdata si ce n’est pas déjà fait !
A+

Continuez votre lecture sur le blog :

twitterlinkedinmail

David Baffaleuf

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.