PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Re : Général » Problème avec la fonction now() » 10/06/2024 11:08:32

plc

Bon, je me réponds à moi même ;-)

Il faut utiliser la fonction clock_timestamp() et non la fonction now()

#2 Re : Général » Problème avec la fonction now() » 10/06/2024 11:02:24

plc

Version courte poour reproduire :

select 'Before begin', now();
begin;
select 'In begin - 1', now();

Attendre un peu

select 'In begin - 2', now();
end;
select 'After begin', now();

Result :

   ?column?   |              now
--------------+-------------------------------
 Before begin | 2024-06-10 11:01:59.470195+02
(1 row)

BEGIN

   ?column?   |              now
--------------+-------------------------------
 In begin - 1 | 2024-06-10 11:01:59.470478+02
(1 row)

   ?column?   |              now
--------------+-------------------------------
 In begin - 2 | 2024-06-10 11:01:59.470478+02
(1 row)

COMMIT

  ?column?   |              now
-------------+-------------------------------
 After begin | 2024-06-10 11:02:10.642165+02
(1 row)

==> "Begin" "fige" la fonction now(); Comment faire pour avoir le véritable timestamp ?

#3 Général » Problème avec la fonction now() » 10/06/2024 09:09:17

plc
Réponses : 2

Bonjour

Je rencontre un problème assez surprenant avec la fonction now() (!)

J'ai une fonction d'intégration de données (qui n'est pas instantanée, loi de là car elle fait des calculs d'intersections dans Postgis). Cette fonction est appelée par un trigger qui se déclenche lorsqu'un buffer de données atteint une certaine taille. Je tente de mesurer le temps d'exécution en gardant une trace dans une table de débug. Cela donne cela (la fonction va appeler la sous fonction Integrate() jusqu'à ce que la source de données soit épuisée. Dans mon cas d'usage cela donne une centaine d'iétartions à chaque fois)


CREATE OR REPLACE FUNCTION IntegrateData()
RETURNS trigger
AS
$$
declare start_time timestamp;
declare trigger_id integer;
declare ndata integer;
declare ndata_start integer;
declare iterations integer;
begin

-- Immediatly reset counter
update import_counter set counter=0, lastrun=now();

select nextval ( 'trigger_id' ) into trigger_id;
select now() into start_time;

select count(*) from import into ndata_start;
insert into debug_trigger values ( trigger_id, start_time, NULL, NULL, NULL, ndata_start, NULL );

select 0 into iterations;

LOOP
   call Integrate();
   select count(*) from import into ndata;
   select iterations + 1 into iterations;
   insert into debug_trigger values ( trigger_id, NULL, now(), NULL, iterations, NULL, ndata);

   EXIT WHEN ndata = 0;
END LOOP;

update import_counter set counter=ndata, lastrun=now();

insert into debug_trigger values ( trigger_id, start_time, now(), now() - start_time, iterations, ndata_start, ndata);

return new;
end;
$$
LANGUAGE plpgsql VOLATILE;

Mon problème est que tous les timestamps que je retrouve dans ma table de debug pour un appel au trigger sont strictement identiques à la milliseconde près. D'après mes tests cela n'est pas possible car la fonction d'intégration n'est pas instantannée, encore moins quand on l'appelle une centaine de fois.

 id |           start            |            stop            | duration | iterations | ndata_start | ndata_stop
----+----------------------------+----------------------------+----------+------------+-------------+------------
  1 | 2024-06-10 08:53:11.893034 |                            |          |            |        1000 |
.../...
  1 | 2024-06-10 08:53:11.893034 | 2024-06-10 08:53:11.893034 | 00:00:00 |        128 |        1000 |          0

J'ai l'impression que la fonction now() est mise en cache par l'optimiseur lors de son premier appel et que du coup les données enregistrées ne reflètent pas la réalité.

Qu'en pensez vous ? Quelle solution ?

Merci

Pied de page des forums

Propulsé par FluxBB