IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut [Firebird 3] Plan d'exécution de requête différent avec 2.5 entrainant un temp d'exécution très long avec 3.0
    Bonjour a tous

    Je viens de passer sous FIREBIRD 3.0

    et j'ai trouvé une différence dans le temps d’exécution d'une requête entre les versions 2.5 et 3.0 qui passe de quelques millisecondes à plusieurs minutes (voire plusieurs dizaines) lié à des variations dans le plan d’exécution proposé par Firebird!

    Voici la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      SELECT MIN(Mouv.Date_mouv)
                              FROM (SELECT N_bague.Id_bague
                                      FROM N_bague
                                    WHERE ((N_bague.Id_centre = 101)
                                          AND (N_bague.Bague BETWEEN 7861001 AND 7862000)
                                          AND (N_bague.Prefixe IS NOT DISTINCT FROM null)
                                          AND (N_bague.Sufixe IS NOT DISTINCT FROM null))) Bague
                                LEFT JOIN(SELECT N_bague_mouv.Id_bague,
                                                 MAX(N_bague_mouv.Date_mouv) Date_mouv
                                            FROM N_bague_mouv
                                            WHERE  n_bague_mouv.efface = 0
                                          GROUP BY N_bague_mouv.Id_bague) Mouv ON (Bague.Id_bague = Mouv.Id_bague)
                                          WHERE Mouv.Date_mouv >= :Date_envoi
    Sous FIREBIRD 2.5, le plan de la requête est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PLAN JOIN (BAGUE N_BAGUE INDEX (IDX_N_BAGUE_PREFIXE, IDX_N_BAGUE_CENTRE_BAGUE), MOUV N_BAGUE_MOUV ORDER UNQ1_N_BAGUE_MOUV INDEX (FK_N_BAGUE_MOUV_BAGUE))
    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 141ms
    Temps moyen d'execution = 141.00 ms
    memoire courante = 36*598*400
    memoire maximum = 36*639*708
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 0
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =1*368
    Mais sous firebird 3.0, le plan généré est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PLAN JOIN (BAGUE N_BAGUE INDEX (IDX_N_BAGUE_PREFIXE, IDX_N_BAGUE_CENTRE_BAGUE), MOUV N_BAGUE_MOUV ORDER FK_N_BAGUE_MOUV_BAGUE INDEX (IDX_N_BAGUE_MOUV_EFFACE))
    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 6m 12s 578ms
    Temps moyen d'execution = 372*578.00 ms
    memoire courante = 61*822*600
    memoire maximum = 70*405*720
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 4*557*439
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =4*559*446
    Mais si j'utilise de plan choisi par 2.5 avec 3.0, le temps d’exécution devient "normal" :
    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 125ms
    Temps moyen d'execution = 125.00 ms
    memoire courante = 81*865*256
    memoire maximum = 87*411*912
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 1*456
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =14*601

    Est ce un bug, dans le choix du plan de la requête ?

    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    je dois avouer n'en rien savoir mais je te propose de passer par des CTE (j'ai horreur des FROM SELECT) ce qui devrait grandement faciliter la lecture voire l'exécution

    AMHA Quelque chose de ce genre devrait faire la même chose en plus vite ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    WITH MOUV AS (SELECT Id_bague,
                                      MAX(Date_mouv) AS Date_mouv
                                      FROM N_bague_mouv
                                      WHERE  efface = 0 AND Date_mouv >= :Date_envoi  
                                      GROUP BY Id_bague),
                     BAGUE AS (SELECT N_bague.Id_bague
                                      FROM N_bague
                                     WHERE id_centre = 101
                                          AND Bague BETWEEN 7861001 AND 7862000
                                          AND Prefixe IS NOT DISTINCT FROM null
                                          AND Sufixe IS NOT DISTINCT FROM null)
     
        SELECT MIN(DATE_MVT) FROM MOUV JOIN BAGUE ON MOUV.id_BAGUE=BAGUE.id_BAGUE
    Question IS NOT DISTINCT FROM NULL ne pourrait pas être un simple IS NOT NULL ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  3. #3
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut dehorter olivier.

    Citation Envoyé par dehorter olivier
    Je viens de passer sous FIREBIRD 3.0
    C'est bien !

    Citation Envoyé par dehorter olivier
    et j'ai trouvé une différence dans le temps d’exécution d'une requête entre les versions 2.5 et 3.0 qui passe de quelques millisecondes à plusieurs minutes
    N'auriez vous pas oublié de faire quelque chose ?
    Genre, la création de vos index lors de votre migration vers Firebird 3.0.
    Il se peut que cet oubli vient dégrader vos performances.

    Oh, que je n'aime pas les sous-requêtes comme vous le faites.
    Pourquoi ne pas utilisez une jointure au lieu de faire une sous-requête ?

    Citation Envoyé par dehorter olivier
    Sous FIREBIRD 2.5, le plan de la requête est le suivant :
    Et qui a créé ce plan sous FireBird 2.5 ? Si c'est vous, alors pourquoi ne pas l'avoir reconduit, tel quel, sous FireBird 3.0 ?
    A priori, je pense que vous avez laissé FireBird faire ses propres choix, qui au final sont désastreux.

    Un plan, c'est normalement vous qui imposer à FireBird comment il doit travailler. Entre autre, le choix des index quand il y en a plusieurs !
    Si votre plan sous FireBird 2.5 vous convient alors reconduisez celui-ci dans FireBird 3.0.

    Citation Envoyé par dehorter olivier
    Est ce un bug, dans le choix du plan de la requête ?
    Ce n'est pas un bug, mais un oubli de votre part.
    Comme vous avez changé de FireBird, je vous conseille, non pas de reprendre tel quel, le plan de FireBird 2.5, mais de refaire les tests afin de trouver celui qui vous convient le mieux sous FireBird 3.0.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  4. #4
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Merci Sergio pour cette réponse.

    Je dois avouer que je n'arrive pas à "rentrer" dans les CTE malgré la lecture répétée de différents papiers la dessus (dont celui de SQLPro)

    J'ai essayé ta requête, et voici les résultats :

    Sous Firebird 2.5 :
    Plan
    PLAN JOIN (MOUV N_BAGUE_MOUV ORDER UNQ1_N_BAGUE_MOUV INDEX (N_BAGUE_MOUV_IDX_DATE), BAGUE N_BAGUE INDEX (PK_N_BAGUE))

    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 875ms
    Temps moyen d'execution = 875.00 ms
    memoire courante = 34*720*696
    memoire maximum = 35*864*724
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 20*008
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =21*051
    Sous Firebird 3.0 :
    Plan
    PLAN JOIN (MOUV N_BAGUE_MOUV ORDER FK_N_BAGUE_MOUV_BAGUE INDEX (N_BAGUE_MOUV_IDX_DATE, IDX_N_BAGUE_MOUV_EFFACE), BAGUE N_BAGUE INDEX (PK_N_BAGUE))

    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 1s 250ms
    Temps moyen d'execution = 1*250.00 ms
    memoire courante = 66*385*864
    memoire maximum = 87*411*912
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 9*714
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =10*969
    C'est un peu moins bon.
    Et en utilisant le plan provenant de la 2.5 :
    Plan
    PLAN JOIN (MOUV N_BAGUE_MOUV ORDER UNQ1_N_BAGUE_MOUV INDEX (N_BAGUE_MOUV_IDX_DATE), BAGUE N_BAGUE INDEX (PK_N_BAGUE))

    ------ Performance information ------
    temps de préparation = 0ms
    Temps d'Execution = 922ms
    Temps moyen d'execution = 922.00 ms
    memoire courante = 66*393*712
    memoire maximum = 87*411*912
    buffers mémoire = 2*048
    Lecure depuis le disque vers le cache = 18*262
    Ecritures du cache vers le disque = 0
    Valider depuis le cache =19*505
    La requête sans CTE donne le résultat plus rapidement (au moins dans ce cas). Cependant, il faut VRAIMENT que je me mette au CTE.

    merci
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  5. #5
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut à tous.

    Soit le CTE de SergioMaster :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    WITH MOUV  AS (SELECT  Id_bague,
                           MAX(Date_mouv) AS Date_mouv
                     FROM  N_bague_mouv
                    WHERE  efface = 0
                      AND  Date_mouv >= :Date_envoi  
                 GROUP BY  Id_bague),
         BAGUE AS (SELECT  N_bague.Id_bague
                     FROM  N_bague
                    WHERE  id_centre = 101
                      AND  Bague BETWEEN 7861001 AND 7862000
                      AND  Prefixe IS NOT DISTINCT FROM null
                      AND  Sufixe  IS NOT DISTINCT FROM null)
     
    SELECT MIN(DATE_MVT)
    FROM MOUV
    JOIN BAGUE
    ON MOUV.id_BAGUE=BAGUE.id_BAGUE;
    Pourquoi la performance est désastreuse ?
    Car dans ce CTE, il y a un jointure "ON MOUV.id_BAGUE=BAGUE.id_BAGUE" sans index !
    Je ne parle pas de l'index qui doit sûrement exister dans vos tables, mais celui du CTE.

    Pourquoi ne pas réécrire votre requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select  min(mouv.date_mvt)
      from       N_bague_mouv as mouv
     inner  join N_bague      as bague
        on  bague.id_bague  = mouv.id_bague
       and  bague.id_center = 101
       and  bague.bague   between 7861001 and 7862000
       and  bague.Prefixe is not null
       and  bague.Sufixe  is not null
     
    where  mouv.efface = 0
      and  mouv.date_mouv >= :Date_envoi);
    Ne pas oublier de vérifier vos index sur :
    --> table "N_bague_mouv", colonne "efface"
    --> table "N_bague_mouv", colonne "date_mouv"

    --> table "N_bague", colonne "id_center"
    --> table "N_bague", colonne "bague"
    --> table "N_bague", colonne "prefix"
    --> table "N_bague", colonne "sufixe"

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 245
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    IS DISTINCT a été inventé parce que (null<>2) retournait Faux alors que (null is distinct from 2) est Vrai.
    "IS NOT DISTINCT FROM null" est donc la même chose que "is null"
    Par ailleurs, j'ai du mal à comprendre ce left join ?
    Est-ce que cette forme ne marche pas aussi bien tout en étant plus claire bien que conservant la sous-requête?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select min(x)                                      
    from (SELECT MAX(m.Date_mouv) as x
      FROM N_bague b
      inner join N_bague_mouv m on m.id_bague=b.id_bague
        and m.efface=0
        and m.Date_mouv>=:Date_envoi  
      WHERE b.Id_centre=101
        and b.Bague BETWEEN 7861001 AND 7862000
        and b.Prefixe is null
        and b.Sufixe is null)
    André

  7. #7
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour et merci

    Citation Envoyé par Artemus24 Voir le message
    N'auriez vous pas oublié de faire quelque chose ?
    Genre, la création de vos index lors de votre migration vers Firebird 3.0.
    Il se peut que cet oubli vient dégrader vos performances.
    Non j'avais regardé


    Citation Envoyé par Artemus24 Voir le message
    Oh, que je n'aime pas les sous-requêtes comme vous le faites.
    Pourquoi ne pas utilisez une jointure au lieu de faire une sous-requête ?
    J'avais fait ces requête, il y a plusieurs années. Et en effet, elle peut très largement être améliorée; je me demande même pour quoi ai-je fait un truc aussi stupide...


    Citation Envoyé par Artemus24 Voir le message
    Et qui a créé ce plan sous FireBird 2.5 ? Si c'est vous, alors pourquoi ne pas l'avoir reconduit, tel quel, sous FireBird 3.0 ?
    A priori, je pense que vous avez laissé FireBird faire ses propres choix, qui au final sont désastreux.
    Oui, j'ai laissé Firebird faire ses choix, je fais confiance Je ne travaille sur les plans que si la vitesse d'exécution me semble trop lente ...

    J'ai reconstruit la requête en utilisant les jointures, et même trouvé un plan qui est meilleur que celui que proposé Firebird

    Citation Envoyé par Artemus24 Voir le message
    Ce n'est pas un bug, mais un oubli de votre part.
    Il n'en demeure pas moins (toute chose étant égale par ailleurs : la présence des index) que le générateur de plan de firebird fait des choses très différentes entre les 2 versions et surtout avec des performances très différentes.



    et pour répondre à Sergio
    Question IS NOT DISTINCT FROM NULL ne pourrait pas être un simple IS NOT NULL ?
    Dans ce cas oui mais en fait, le NULL est en fait un paramètre qui est parfois est NULL et d'autres fois, non d'où l'utilisation de "IS NOT DISTINCT FROM"
    Merci d'ajouter un sur les tags qui vous ont aidé

  8. #8
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    re Bonjour

    Citation Envoyé par Artemus24 Voir le message
    Pourquoi ne pas réécrire votre requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select  min(mouv.date_mvt)
      from       N_bague_mouv as mouv
     inner  join N_bague      as bague
        on  bague.id_bague  = mouv.id_bague
       and  bague.id_center = 101
       and  bague.bague   between 7861001 and 7862000
       and  bague.Prefixe is not null
       and  bague.Sufixe  is not null
     
    where  mouv.efface = 0
      and  mouv.date_mouv >= :Date_envoi);
    @+
    C'est la requête que je venais d'écrire J'ai donc progressé
    Merci d'ajouter un sur les tags qui vous ont aidé

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour

    Citation Envoyé par alanglet Voir le message
    Est-ce que cette forme ne marche pas aussi bien tout en étant plus claire bien que conservant la sous-requête?
    Oui, oui absolument (une erreur de jeunesse ;( )
    Voir mon post précédent qui a télescopé le votre

    a+
    olivier

    PS : et votre requête correspond mieux à mes besoins, merci
    Merci d'ajouter un sur les tags qui vous ont aidé

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Artemus24 Voir le message
    Soit le CTE de SergioMaster :
    Pourquoi la performance est désastreuse ?
    Car dans ce CTE, il y a un jointure "ON MOUV.id_BAGUE=BAGUE.id_BAGUE" sans index !
    Je ne parle pas de l'index qui doit sûrement exister dans vos tables, mais celui du CTE.
    C'est exact, en fait je voulais surtout faire remarquer que il était difficile de bien s'y retrouver et j'ai repris le code simplement en partie sans y réfléchir d'avantage

    Citation Envoyé par Artemus24 Voir le message
    Pourquoi ne pas réécrire votre requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    select  min(mouv.date_mvt)
      from       N_bague_mouv as mouv
     inner  join N_bague      as bague
        on  bague.id_bague  = mouv.id_bague
       and  bague.id_center = 101
       and  bague.bague   between 7861001 and 7862000
       and  bague.Prefixe is not null
       and  bague.Sufixe  is not null
     
    where  mouv.efface = 0
      and  mouv.date_mouv >= :Date_envoi);
    c'est pratiquement la conclusion à laquelle je suis arrivé en relisant l'ensemble mais je pense que l'on a pas tous les éléments en main
    en autre je pense que ces constantes 101, 7861001 ... 7862000 voir même les is not distinct from null (forme que je ne comprend pas vraiment) sont en fait des paramètres. Comme le suggérerait le ate_Envoi cette requête me semble est une requête codée dans un programme Delphi mais peut être que je m'avance

    Ceci étant, j'ai refait un survol de FB3 Migration Guide, il y est clairement indiqué que des requêtes auparavant performantes pouvaient être ralenties. Les principales raisons tenant au changement de statistiques d'index ou aux changements de l'optimiseur. Pour la première un SET STATISTICS devrait y pallier pour la seconde un rapport sur le tracker est demandé et en contournement forcer le PLAN (ce que tu avait fait intuitivement?)

    enfin, s'il s'agit, comme je le pense, d'une requête paramétrée construite avec/dans un programme Delphi as-tu songé à la vue (VIEW) ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  11. #11
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut à tous.

    Citation Envoyé par SergioMaster
    C'est exact, en fait je voulais surtout faire remarquer que il était difficile de bien s'y retrouver et j'ai repris le code simplement en partie sans y réfléchir d'avantage
    Ce n'est pas une critique, je te rassure. J'ai peut-être un peu beaucoup exagéré en disant que le performance était désastreuse.
    Je tenais simplement à souligner l'absence de l'index sur la jointure et seulement cela !

    Citation Envoyé par SergioMaster
    c'est pratiquement la conclusion à laquelle je suis arrivé en relisant l'ensemble mais je pense que l'on a pas tous les éléments en main
    Nous n'avons qu'une vue partielle du problème et elle ne peut pas se résumer seulement à la réécriture de la requête.
    L'organisation des tables est fréquemment une cause du manque de performance des requêtes.
    La modélisation ne consiste pas à faire seulement une organisation fonctionnelle des données.
    Il faut aussi penser aux traitements et en particulier, à la maintenance et aux performances qui sont fréquemment délaissées.

    Citation Envoyé par SergioMaster
    voir même les is not distinct from null (forme que je ne comprend pas vraiment)
    Je n'ai pas creusé la question.

    Citation Envoyé par alanglet
    IS DISTINCT a été inventé parce que (null<>2) retournait Faux alors que (null is distinct from 2) est Vrai.
    Vous n'avez pas compris (ALANGLET) ce que représente NULL ! NULL n'est pas une valeur mais tout au contraire, une absence de valeur.
    De ce fait, la seule bonne façon de tester est de mettre "is not null" ou encore "is null" en plus du test (val <> 2) si vous désirez récupérer les valeurs de cette colonne, différente de 2 et du marqueur NULL !

    Vous dites que "NULL IS DISTINCT FROM 2". Oui, sur le principe, je suis d'accord.
    Mais je le rappelle encore une fois, NULL n'est pas une valeur.
    Donc comparer NULL à n'importe quoi retourne nécessairement faux.
    Même si vous écrivez "NULL <> NULL" retournera faux car ce n'est pas la bonne écriture.
    A lire : http://sqlpro.developpez.com/cours/null/

    SergioMaster, je pense que le reste du post #10 ne m'est pas adressé.

    Sinon, j'ai voulu faire quelques tests sur le plan sans bien comprendre pourquoi cela ne fonctionne pas comme je l'entends.
    Je suis seulement sous FireBird 3.0.0. Il se peut que cela fonctionne différemment dans IEB.
    J'ai même voulu tester "SET STATISTICS INDEX IDX" et je n'ai aucun résultat.
    Y-a-t-il quelque chose à mettre en place, à paramétrer afin d'avoir les statistiques de performances sur une requête ?

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  12. #12
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour à tous
    et désolé du retard de ma réponse

    Pour tenter de répondre à la question sur IS NOT DISTINCT FROM,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       .... 
       ID_CENTRE     SMALLINT NOT NULL,
        PREFIXE       CHAR(5),
        BAGUE         INTEGER DEFAULT 0 NOT NULL,
        SUFIXE        CHAR(5),
        ....
    Comme vous le constatez PREFIXE et SUFIXE peuvent être NULL, d'où l'utilisation de cet opérateur pour à la fois lancer des recherches avec PREFIXE/SUFIXE NULL ou non-NULL comme le tableau ci-dessous l'indique.
    Table 12.1. Comparison of [NOT] DISTINCT to “=” and “<>”
    Operand characteristics
    = NOT DISTINCT <> DISTINCT
    Same value true true false false
    Different values false false true true
    Both NULL NULL true NULL false
    One NULL NULL false NULL true
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT N_bague.Id_bague
                                      FROM N_bague
                                     WHERE id_centre = 101
                                          AND Bague BETWEEN 7861001 AND 7862000
                                          AND Prefixe IS NOT DISTINCT FROM null
                                          AND Sufixe IS NOT DISTINCT FROM null
    En fait, il s'agit bien d'une requête paramétrée que j'aurais dû peut être écrire sous cette forme pour éviter toute ambiguïté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT N_bague.Id_bague
                                      FROM N_bague
                                     WHERE id_centre = :Centre
                                          AND Bague BETWEEN :Debut AND :Fin
                                          AND Prefixe IS NOT DISTINCT FROM :Pref
                                          AND Sufixe IS NOT DISTINCT FROM :suf
    Par ailleurs, ces 4 colonnes constituent une contrainte d'unicité
    Évidemment un index a été crée pour tenir comme de la sélectivité des différents éléments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE UNIQUE INDEX IDX_N_BAGUE_CENTRE_BAGUE ON N_BAGUE (BAGUE, PREFIXE, SUFIXE, ID_CENTRE)
    . La colonne BAGUE est en premier parce que c'est celle qui a le meilleur indice de sélectivité et va donc renvoyer le moins de ligne.

    Sur la forme de la requête présentée au premier post, il est clair qu'elle TRES MAL écrite (sans discussion possible) [je ne vois même pas le cheminement "intellectuel" qui m'a fait aboutir à çà !]....

    En tout cas, je vais revoir toutes mes anciennes requêtes parce qu'il n'y a aucune raison qu'ils n'en restent pas des aussi magnifiquement merdiques !

    Mais l'interrogation de ce premier post était de tenter de comprendre pourquoi la même requête avec le même plan d'exécution (et avec les statistiques recalculées SET STATISTICS INDEX), la durée d'exécution est aussi différente ???
    Comme je suggère SergioMaster, je vais me pencher un peu plus sur le FB3 Migration Guide (si j'y comprends quelque chose :?)


    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  13. #13
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonsoir,

    je me demande si le IS NOT DISTINCT FROM est bien le bon choix et n'amènerai pas des lenteurs (sauf si préfixe et suffixe étaient indexés) ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  14. #14
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut à tous.

    Voici un petit exercice :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    CREATE DATABASE '..\Data\Base.fdb' page_size 4096 DEFAULT CHARACTER SET ISO8859_1;
     
    -- ============
    -- table "test"
    -- ============
     
    create table test (
    id       integer not null,
    prefixe  integer,
    suffixe  integer
    );
     
    -- =======================
    -- insertion dans 'test'
    -- =======================
     
    insert into test (id,prefixe,suffixe) values (1, null, null);
    insert into test (id,prefixe,suffixe) values (2, null,   55);
    insert into test (id,prefixe,suffixe) values (3, null,   66);
    insert into test (id,prefixe,suffixe) values (4,   55, null);
    insert into test (id,prefixe,suffixe) values (5,   66, null);
    insert into test (id,prefixe,suffixe) values (6,   55,   66);
    insert into test (id,prefixe,suffixe) values (7,   66,   55);
    insert into test (id,prefixe,suffixe) values (8,   55,   55);
    insert into test (id,prefixe,suffixe) values (9,   66,   66);
     
    -- ================
    -- Vidage de 'test'
    -- ================
     
    select * from test;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               2       <null>           55
               3       <null>           66
               4           55       <null>
               5           66       <null>
               6           55           66
               7           66           55
               8           55           55
               9           66           66
     
     
    -- ===========
    -- Requête N°1
    -- ===========
     
    select * from test where prefixe is                   null;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               2       <null>           55
               3       <null>           66
     
    select * from test where prefixe is not distinct from null;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               2       <null>           55
               3       <null>           66
     
     
    -- ===========
    -- Requête N°2
    -- ===========
     
    select * from test where suffixe is                   null;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               4           55       <null>
               5           66       <null>
     
    select * from test where suffixe is not distinct from null;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               4           55       <null>
               5           66       <null>
     
     
    -- ===========
    -- Requête N°3
    -- ===========
     
    select * from test where prefixe is null or prefixe  <> 55;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               2       <null>           55
               3       <null>           66
               5           66       <null>
               7           66           55
               9           66           66
     
    select * from test where prefixe is     distinct from   55;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               2       <null>           55
               3       <null>           66
               5           66       <null>
               7           66           55
               9           66           66
     
     
    -- ===========
    -- Requête N°4
    -- ===========
     
    select * from test where suffixe is null or suffixe  <> 55;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               3       <null>           66
               4           55       <null>
               5           66       <null>
               6           55           66
               9           66           66
     
    select * from test where suffixe is     distinct from   55;
     
              ID      PREFIXE      SUFFIXE
    ============ ============ ============
               1       <null>       <null>
               3       <null>           66
               4           55       <null>
               5           66       <null>
               6           55           66
               9           66           66
     
     
    exit;
     
    Appuyez sur une touche pour continuer...
    Aucun intérêt ! Pourquoi ? Car avec le "is null" ou le "is not null", on peut reproduire la même chose.

    Si tu fais une sélection sur la colonne "prefixe", quel intérêt d'avoir aussi les null ?
    J'ai surtout l'impression que le marqueur NULL est une notion qui est mal comprise.
    Ce n'est pas une valeur, mais une absence de valeur. De ce fait, il est aberrant de le traiter comme une valeur.

    Inversement, il se peut que vous vous êtes trompé en utilisant ce marqueur NULL.
    Le mieux aurait été de mettre une valeur par défaut. Par exemple le zéro !
    Si le zéro a la même sens que les autres valeurs, vous ne savez pas faire la distinction entre la valeur par défaut et la valeur zéro.
    C'est pourquoi, le marqueur NULL prend aussi le sens de valeur par défaut, ou si vous préférez, je ne sais pas quoi mettre car en cet instant là, la valeur est inconnue.

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  15. #15
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour SergioMaster

    Citation Envoyé par SergioMaster Voir le message
    Bonsoir,

    je me demande si le IS NOT DISTINCT FROM est bien le bon choix et n'amènerai pas des lenteurs (sauf si préfixe et suffixe étaient indexés) ?
    Oui bien sûr. Ils sont même intégrés à l'index gérant la contrainte d'unicité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE UNIQUE INDEX IDX_N_BAGUE_CENTRE_BAGUE ON N_BAGUE (BAGUE, PREFIXE, SUFIXE, ID_CENTRE);
    Il me semble avoir lu dans un guide sur la version 2.5 que la gestion des index avec des "valeurs" NULLs ne posait plus de problémes par rapport à la version 1.5.
    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

  16. #16
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour Artemus

    Citation Envoyé par Artemus24 Voir le message
    Salut à tous.

    Aucun intérêt ! Pourquoi ? Car avec le "is null" ou le "is not null", on peut reproduire la même chose.
    Dans ta liste de requête, il manque
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select * from test where prefixe is not distinct from 55;
    qui doit fournir toutes les données avec 55.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ID	PREFIXE	SUFFIXE
    4	55	NULL
    6	55	66
    8	55	55
    Il s'agit d'une requête paramétrée, passant (en autre le paramètres du PREFIXE). C'est pour cela que la requête est construite via IS NOT DISTICNT FROM qui permet de passer à la requête l'info du préfixe à rechercher (une valeur ou une absence de valeur NULL).


    Citation Envoyé par Artemus24 Voir le message
    Si tu fais une sélection sur la colonne "prefixe", quel intérêt d'avoir aussi les null ?
    Je ne veux pas aussi les NULLs. Je veux juste les lignes concernant le préfixe envoyé dans les paramètres; Soit une valeur, soit les Nulls


    Citation Envoyé par Artemus24 Voir le message
    J'ai surtout l'impression que le marqueur NULL est une notion qui est mal comprise.
    Ce n'est pas une valeur, mais une absence de valeur. De ce fait, il est aberrant de le traiter comme une valeur.
    Je suis bien d'accord, et c'est bien l'absence de valeur qu'il m'arrive de traiter

    Citation Envoyé par Artemus24 Voir le message
    Inversement, il se peut que vous vous êtes trompé en utilisant ce marqueur NULL.
    Le mieux aurait été de mettre une valeur par défaut. Par exemple le zéro !
    Si le zéro a la même sens que les autres valeurs, vous ne savez pas faire la distinction entre la valeur par défaut et la valeur zéro.
    En l’occurrence, rien n'interdit l'utilisation d'un préfixe ayant la valeur 0.

    NB : La colonne PREFIXE est du type CHAR(), mais cela ne change rien au propos

    Citation Envoyé par Artemus24 Voir le message
    C'est pourquoi, le marqueur NULL prend aussi le sens de valeur par défaut, ou si vous préférez, je ne sais pas quoi mettre car en cet instant là, la valeur est inconnue.
    @+
    Il s'agit bien d'un choix. Quand la "valeur" (je ne sais pas quoi dire ? information?) est NULL, c'est bien parce qu'il n'existe pas de préfixe.
    Merci d'ajouter un sur les tags qui vous ont aidé

  17. #17
    Expert éminent sénior Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 380
    Points : 19 062
    Points
    19 062
    Par défaut
    Salut dehorter olivier.

    Je ne vais pas m'étendre sur cette question d'écriture qui n'est pas, il me semble, une norme officielle.

    Citation Envoyé par dehorter olivier
    Je ne veux pas aussi les NULLs
    Mais si. Tu veux en plus du test, les lignes dont la colonne est marquée NULL.

    Mais le fond du problème n'est pas cette clause, mais ce que tu recherches réellement.

    Si tu prends une colonne de type caractères, je préfère de loin le type "varchar(xx)".
    Avec ce type, on peut initialisé la chaîne à vide.
    Et vide à bien un sens particulier que tu peux gérer distinctement du NULL.

    Si le NULL désigne une absence de valeur, il ne doit pas se gérer comme une valeur.
    Je sais que c'est absurde ce que je viens de dire, mais pourtant, c'est souvent le cas !
    Mais que signifie exactement le NULL ?

    Le NULL désigne une valeur inconnue.
    Oui mais le vide désigne quoi ?
    Le vide désigne, non pas une valeur inconnue, mais simplement le fais qu'à cet instant, tu ignores la valeur que tu vas lui affecter.
    Autrement dit, un peu plus tard, tu vas renseigner cette colonne qui est à vide, par sa valeur définitive.

    Comment faire la distinction et gérer ces deux notions (vide et NULL) ?
    Bonne question mais pas nécessairement une bonne réponse.

    Je considère que la valeur par défaut d'une chaîne de caractères est vide et non NULL.
    Que cela dépend des règles fonctionnelles que tu veux mettre en place.
    Maintenant, est-il judicieux de ne rien mettre comme valeur dans une colonne ?

    Cela dépend comment vous travailler et du sens que vous attribuez au particularité de cette colonne.
    Si la colonne est un prix, que signifie le zéro ou le NULL ?
    Un prix à zéro signifie que c'est gratuit. Mais est-ce le cas ?
    Je ne saurais répondre à cette question sans faire une étude fonctionnelle sur les besoins et les significations de cette colonne.
    Inversement, si pour une raison indépendante de votre volonté, on ne vous a pas encore communiqué les prix, je peux comprendre le marquage à NULL.

    Mais pourquoi traiter cela dans un projet ?
    Si c'est un cas particulier qui dénombre les lignes ayant un prix non renseigné (marqué à NULL), je peux comprendre.
    Car la finalité de cette particularité est bien de venir renseigné ce qui ne l'a pas été au préalable.

    Dans le stockage des informations d'une table, que signifie fonctionnellement une colonne marqué à NULL ?
    Il n'en ai pas de même pour une requête où l'on utilise parfois cette astuce pour récupérer des lignes non appareillées.

    Vous allez traiter des lignes qui sont marqués à NULL.
    Expliquez moi fonctionnellement sa signification ? Ça n'a pas de sens !

    @+
    Si vous êtes de mon aide, vous pouvez cliquer sur .
    Mon site : http://www.jcz.fr

  18. #18
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 038
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 038
    Points : 40 943
    Points
    40 943
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Oui bien sûr. Ils sont même intégrés à l'index gérant la contrainte d'unicité
    attention cela ne veut pas dire que ces colonnes sont indexées, juste qu'elles composent un index

    bon en fait de toute façon, perso j'aurais plutôt utilisé des macros dans la requête pour cette partie
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  19. #19
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour
    et MERCI, MERCI beaucoup pour cette explication (en faire une FAQ ?)

    Je n'avais pas pensé au "Vide" ce qui est somme toute assez bête de ma part
    et me convient tout à fait avec cette définition.
    a+
    olivier

    Citation Envoyé par Artemus24 Voir le message
    Salut dehorter olivier.

    Je ne vais pas m'étendre sur cette question d'écriture qui n'est pas, il me semble, une norme officielle.


    Mais si. Tu veux en plus du test, les lignes dont la colonne est marquée NULL.

    Mais le fond du problème n'est pas cette clause, mais ce que tu recherches réellement.

    Si tu prends une colonne de type caractères, je préfère de loin le type "varchar(xx)".
    Avec ce type, on peut initialisé la chaîne à vide.
    Et vide à bien un sens particulier que tu peux gérer distinctement du NULL.

    Si le NULL désigne une absence de valeur, il ne doit pas se gérer comme une valeur.
    Je sais que c'est absurde ce que je viens de dire, mais pourtant, c'est souvent le cas !
    Mais que signifie exactement le NULL ?

    Le NULL désigne une valeur inconnue.
    Oui mais le vide désigne quoi ?
    Le vide désigne, non pas une valeur inconnue, mais simplement le fais qu'à cet instant, tu ignores la valeur que tu vas lui affecter.
    Autrement dit, un peu plus tard, tu vas renseigner cette colonne qui est à vide, par sa valeur définitive.

    Comment faire la distinction et gérer ces deux notions (vide et NULL) ?
    Bonne question mais pas nécessairement une bonne réponse.

    Je considère que la valeur par défaut d'une chaîne de caractères est vide et non NULL.
    Que cela dépend des règles fonctionnelles que tu veux mettre en place.
    Maintenant, est-il judicieux de ne rien mettre comme valeur dans une colonne ?

    Cela dépend comment vous travailler et du sens que vous attribuez au particularité de cette colonne.
    Si la colonne est un prix, que signifie le zéro ou le NULL ?
    Un prix à zéro signifie que c'est gratuit. Mais est-ce le cas ?
    Je ne saurais répondre à cette question sans faire une étude fonctionnelle sur les besoins et les significations de cette colonne.
    Inversement, si pour une raison indépendante de votre volonté, on ne vous a pas encore communiqué les prix, je peux comprendre le marquage à NULL.

    Mais pourquoi traiter cela dans un projet ?
    Si c'est un cas particulier qui dénombre les lignes ayant un prix non renseigné (marqué à NULL), je peux comprendre.
    Car la finalité de cette particularité est bien de venir renseigné ce qui ne l'a pas été au préalable.

    Dans le stockage des informations d'une table, que signifie fonctionnellement une colonne marqué à NULL ?
    Il n'en ai pas de même pour une requête où l'on utilise parfois cette astuce pour récupérer des lignes non appareillées.

    Vous allez traiter des lignes qui sont marqués à NULL.
    Expliquez moi fonctionnellement sa signification ? Ça n'a pas de sens !

    @+
    Merci d'ajouter un sur les tags qui vous ont aidé

  20. #20
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 146
    Points : 1 412
    Points
    1 412
    Par défaut
    Bonjour



    Citation Envoyé par SergioMaster Voir le message
    Bonjour,


    attention cela ne veut pas dire que ces colonnes sont indexées, juste qu'elles composent un index
    Oui les colonnes sont bien indexées.


    Citation Envoyé par SergioMaster Voir le message
    bon en fait de toute façon, perso j'aurais plutôt utilisé des macros dans la requête pour cette partie
    Je n'ai jamais entendu parler de macros dans firebird, de quoi s'agit-il ?

    merci
    a+
    olivier
    Merci d'ajouter un sur les tags qui vous ont aidé

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Temps d'exécution de requête différent entre SSMS et C#
    Par Vonziz dans le forum Développement
    Réponses: 12
    Dernier message: 12/09/2013, 09h07
  2. Temps d'exécution sous-requête
    Par ThatGuy dans le forum Requêtes
    Réponses: 2
    Dernier message: 22/05/2012, 16h39
  3. Réponses: 6
    Dernier message: 27/07/2010, 15h28
  4. [WD15] Temps d'exécution des requêtes
    Par thierrybatlle dans le forum WinDev
    Réponses: 7
    Dernier message: 18/02/2010, 16h21
  5. Erreur OEM 10gR2 - Temps d'exécution des requêtes
    Par fabien.morel2002 dans le forum Administration
    Réponses: 0
    Dernier message: 30/11/2009, 16h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo