Vous n'êtes pas identifié(e).
Pages : 1
Bon, je me réponds à moi même ;-)
Il faut utiliser la fonction clock_timestamp() et non la fonction now()
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 ?
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
Pages : 1