La compilation JIT bénéficie surtout aux requêtes de longue durée et limitées par le processeur. Ce seront souvent des requêtes analytiques. Pour les requêtes courtes, le surcoût apporté par la compilation JIT sera souvent supérieur au temps qu'elle permet de gagner.
Pour déterminer si la compilation JIT doit être utilisée, le coût total estimé d'une requête (voir Chapitre 76 et Section 20.7.2) est utilisée. Le coût estimé de la requête sera comparé à la configuration du paramètre jit_above_cost. Si le coût est supérieur, une compilation JIT sera opérée. Deux décisions supplémentaires sont encore nécessaires. Premièrement, si le coût estimé est plus important que la configuration de jit_inline_above_cost, les petites fonctions et opérateurs utilisés dans la requête seront intégrés. Ensuite, si le coût est plus important que la valeur de jit_optimize_above_cost, les optimisations coûteuses sont appliquées pour améliorer le code généré. Chacune de ses options augmente la surcharge de la compilation JIT mais peut réduire considérablement la durée d'exécution.
Ces décisions basées sur les coûts seront réalisées au moment de la planification, pas au moment de l'exécution. Ceci signifie que, quand des instructions préparées sont utilisées et qu'un plan générique est utilisé (voir PREPARE), les valeurs des paramètres de configuration en effet au moment de la préparation contrôlent les décisions, pas les valeurs des paramètres au moment de l'exécution.
Si jit est à off
,
ou si aucune implémentation du JIT n'est disponible
(par exemple parce que le serveur a été compilé sans
--with-llvm
), le JIT ne sera pas
opéré, même s'il est considéré comme bénéfique selon les critères
ci-dessus. Placer jit à off
prend effet au moment de la planification comme de l'exécution.
EXPLAIN peut être utilisé pour voir si le JIT est utilisé ou pas. Par exemple, voici une requête n'utilisant pas le JIT :
=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1) -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1) Planning Time: 0.116 ms Execution Time: 0.365 ms (4 rows)
Étant donné le coût de la planification, il est parfaitement raisonnable que le JIT ne soit pas utilisé, son coût aurait été supérieur au temps potentiellement épargné. Ajuster les limites de coût amèneront son utilisation :
=# SET jit_above_cost = 10; SET =# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; QUERY PLAN ------------------------------------------------------------------------------------------------------------- Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1) -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1) Planning Time: 0.133 ms JIT: Functions: 3 Options: Inlining false, Optimization false, Expressions true, Deforming true Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms Execution Time: 7.416 ms
Comme on le voit ici, le JIT a été utilisé, mais pas l'intégration et l'optimisation coûteuse. Si jit_inline_above_cost et jit_optimize_above_cost étaient abaissés comme jit_above_cost, cela changerait.