• [^] # Re: Je ne sais pas si c'est la bonne méthode, mais....

    Posté par . En réponse au message champs "durée" et postgres. Évalué à 1.

    Pour ce qui est de la tronche de la table, je vais réflechir au fait
    d'enregistrer une période par ligne plutôt que d'en avoir deux
    en cas de chevauchement (mais je dois faire des stats par jour férié
    alors j'ai pensé à y inclure le jour, enfin bon, à voir...).

    C'est simplement qu'après avoir peiné 15 ans sur des bases
    conséquentes dénormalisées à outrance, j'ai enfin la chance de
    pouvoir créer une base (une 50aine de tables) from scratch, j'en
    profite pour la faire bien d'équerre !! :-)

    Sinon, oui, je vais regarder pour les types "maison", c'est vrai que
    c'est pas mal cette possibilité d'extension...

    Enfin, ça peut peut-être servir à d'autres, j'ai fait 2 tests de perfs,
    la table contient 100.000 lignes, le serveur est un amd 2GHz avec
    512Mo de ram et un disque IDE de 80 Go et os=debian testing:

    La première requête suivante prend 0,3 sec (lancée plusieurs
    fois pour annuler l'effet de cache) :

    select
    id_pers,
    sum(duree)
    from
    vu_heur_reel_duree
    group by
    id_pers

    La vue appellée étant:

    create or replace view vu_heur_reel_duree(id_pers,jour,duree) as
    select
    hr.id_pers,
    hr.jour,
    case
    when (duree is not null) then (hr.duree - '00:00:00')
    when (hr.heure_fin >= hr.heure_deb) then
    (hr.heure_fin - hr.heure_deb)
    else ('23:59:59' - hr.heure_deb + '00:00:01')
    end
    from
    tb_heur_reel hr;

    Avec la bidouille de rajouter une seconde dans l'expression, ça
    marche...

    Le 2eme test, je l'ai fait avec une fonction que voila:

    create or replace function fc_elapsed_time(
    time without time zone,
    time without time zone,
    time without time zone)
    returns time without time zone as '
    declare duration alias for 1ドル;
    declare start_time alias for 2ドル;
    declare end_time alias for 3ドル;
    begin
    if (duration is null) then
    if (end_time >= start_time) then
    return end_time - start_time;
    else
    -- hack to handle substract from midnight
    return ''23:59:59'' - start_time + ''00:00:01'';
    end if;
    else
    return duration;
    end if;
    return;
    end;
    ' language 'plpgsql';

    Et la requête (sur la table directement):

    select
    id_pers,
    sum(fc_elapsed_time(duree,heure_deb,heure_fin))
    from
    tb_heur_reel
    group by
    id_pers;

    Ca renvoie évidemment la même chose, mais ça met 2 secondes
    soit 6 fois plus !

    La différence est insignifiante sur de petits volumes (qq milliers de
    lignes) mais l'écart se creuse quand on atteint les volumes de
    "production".

    Comme je vois que tu bosses aussi sur un soft de pointage, as-tu
    prévu qq chose pour les changements heure été/hiver ?