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

Requêtes et SQL. Discussion :

Plantage requête classique


Sujet :

Requêtes et SQL.

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2014
    Messages : 17
    Points : 13
    Points
    13
    Par défaut Plantage requête classique
    Bonjour,

    Je vous expose mon problème :

    Je dispose de deux tables : Une table de données : Table1 et une table contenant des références : REF
    La mécanique est simple, il faut que je vérifie que le champ1 et le champ2 de Table1 existent dans REF en étant égales aux ChampAA + ChampBB de REF.
    Voici le premier test à faire :

    Champ 1 et champ 2 directement dans [REF]
    Voici la requête SQL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Select Table1.* From Table1, REF, REF AS REF_1
    Where (
    ([Table1]![Champ1]<>([REF]![ChampAA] & " - " & [REF]![ChampBB]) 
    AND
    ([Table1]![Champ2]<>([REF_1]![ChampAA] & " - " & [REF_1]![ChampBB]));
    Comme vous pouvez le voir, j'ai créé un Alias de la table REF.

    Mon problème : si je mets des = cela semble fonctionner par contre si je met les <> ca boucle à l'infini... Je précise que le = me renvoie 500 enregistrements et qu'il y a au total 30 000 enregistrements

    Pouvez-vous m'aider svp ?

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 857
    Points
    56 857
    Billets dans le blog
    40
    Par défaut
    Bonsoir,

    Citation Envoyé par niKgir Voir le message
    si je met les <> ca boucle à l'infini...
    C'est que le nombre d'enregistrements retournés de cette façon est TRES élevé...

    Tu peux partir de ta requête avec l'égalité, en supposant qu'elle retourne bien le résultat souhaité, et en faire une sous-requête.

    La requête principale est construite à partir des enregistrements de la table1 qui ne figurent pas dans la sous-requête. C'est ce qu'on appelle une requête de non correspondance, tu peux la faire avec les assistants des requêtes.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2014
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Merci beaucoup pour ton aide même si je n'ai pas tout compris.

    Voici ma requête parfaitement écrite :

    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
    SELECT MagisterV1.*
    FROM PNF_REF_PR, MagisterV1, PNF_Ref_PR AS PNF_REF_PR_1
    WHERE ( 
    (
    ([MagisterV1]![Lieu_Depart]=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Depart]&"-00")=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Depart]&"-BV")=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    )
    AND
    (
    ([MagisterV1]![Lieu_Arrivee]=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Arrivee]&"-00")=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Arrivee]&"-BV")=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    )
    );
    Elle est testée sur un jeu de données réduit et fonctionne.

    Maintenant quand je passe sur les données réelles à savoir 30 000 enregistrements... Ben ca plante..

    Ma question :

    1/ Est-il possible que la requête génère plus d'enregistrements prévus en fonction des combianaisons qu'elle ne devrait pas ?--> Peu probable dans mon jeu de données, j'ai mis des doublons...
    2/ Est ce que 30K enregistrements font beaucoup pour une requête de ce type ?
    3/ Quelles sont les solutions possibles pour que cette requête s'éxécute correctement ?

    D'avance merci pour votre aide.

  4. #4
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 857
    Points
    56 857
    Billets dans le blog
    40
    Par défaut
    Citation Envoyé par niKgir Voir le message
    Elle est testée sur un jeu de données réduit et fonctionne.

    Maintenant quand je passe sur les données réelles à savoir 30 000 enregistrements... Ben ca plante..
    C'est cette requête même avec l'égalité qui "plante" ou une autre (avec des <> au lieu des = comme tu avais dit dans don 1er message) ?

    Que veux-tu dire par "ça plante" ? Message d'erreur ou elle mouline tout le temps

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2014
    Messages : 17
    Points : 13
    Points
    13
    Par défaut Merci pour ton aide
    Oui c'est cette requête qui mouline (pas de plantage) sur 30 000 enregistrements. Elle a été testée sur un jeu de données réduit (6 enregistrements) et elle fonctionne.

    C'est le mystère total...

  6. #6
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 620
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 620
    Points : 56 857
    Points
    56 857
    Billets dans le blog
    40
    Par défaut
    Faut dire que la condition Where n'est pas très sympathique...

    Beaucoup de or, and avec des concaténations, les index ne peuvent pas jouer leur rôle.

    Peut-être en décomposant :

    1 sous-requête avec la condition WHERE portant uniquement sur les [Lieu_Depart]
    1 sous-requête avec la condition WHERE portant uniquement sur les [Lieu_Arrivee]

    comme il faut faire un AND, une dernière requête qui ne retient que les enregistrements qui sont dans les deux sous-requêtes.

    Pas évident qu'on y gagne

  7. #7
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir niKgir et Fabien,


    Citation Envoyé par niKgir Voir le message
    C'est le mystère total...
    J’ai consulté madame Irma qui voit tout, entend tout et sait tout. De notre entrevue j’ai tiré quelques informations.

    Reprenons votre requête :

    Code SQL : 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
    SELECT MagisterV1.*
    FROM PNF_REF_PR, MagisterV1, PNF_Ref_PR AS PNF_REF_PR_1
    WHERE ( 
    (
    ([MagisterV1]![Lieu_Depart]=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Depart]&"-00")=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Depart]&"-BV")=([PNF_REF_PR]![Code_TT0020_Localite] & "-" & [PNF_REF_PR]![Code_TT0020_chantier]))
    )
    AND
    (
    ([MagisterV1]![Lieu_Arrivee]=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Arrivee]&"-00")=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    or
    (([MagisterV1]![Lieu_Arrivee]&"-BV")=([PNF_REF_PR_1]![Code_TT0020_Localite] & "-" & [PNF_REF_PR_1]![Code_TT0020_chantier]))
    )
    );


    Je n’ai pas capté toutes vos concaténations de chaînes, mais une chose est sûre : vous avez droit à un magnifique double produit cartésien :

    PNF_REF_PR X MagisterV1 X PNF_REF_PR

    Car les « OR » empêchent manifestement de transformer un produit en jointure ou autre opération pouvant normalement être rendue performante.

    En l’occurrence, le SGBD balaie complètement une 1re table, par exemple MagisterV1 et pour chaque ligne lue, balaie complètement la 2e table, à savoir la table PNF_REF_PR, pour vérifier si les conditions figurant dans la requêtes sont satisfaites.

    Supposons que la table MagisterV1 contienne 30000 lignes et que la table PNF_REF_PR en contienne 10000 (quel est en fait le nombre réel de ces lignes ?), le nombre de comparaisons, disons d’accès logiques, est donc de l’ordre de :

    30000 X 10000 = 3.10^8

    Ce qui n’est pas négligeable... Mais il y a encore un tour de manège à effectuer, auquel participent le résultat produit et à nouveau PNF_REF_PR. Supposons que le résultat produit soit de 1000 lignes. Après ce tour supplémentaire, le nombre total d’accès logiques est de l’ordre de :

    30000 X 10000 X 1000 X 10000 = 3.10^15, si je compte bien...

    Ou, si le moteur « optimise » :

    30000 X 10000 X 10000 = 3.10^12...


    Un tel nombre de lectures de lignes se traduit par un certain temps, plus qu’il n’en faut au fût d’un canon pour se refroidir (ayant été chef de char Patton je peux en parler...)

    Dans cette affaire, pour arriver à des temps raisonnables, il est impératif de :

    1) Faire jouer les index plein pot ;

    2) Transformer le produit en somme.

    Comme je n’ai pas tout compris de votre requête, j’en propose une un peu du même genre (voir tout en bas).

    Créons d’abord un jeu de tables :

    TABLE T1
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     CREATE TABLE T1 
    (
    K1         INT             NOT NULL,
    A1         CHAR(4)         NOT NULL,
    A2         CHAR(4)         NOT NULL,
    A3         CHAR(4)         NOT NULL,
    B1         CHAR(4)         NOT NULL,
    B2         CHAR(4)         NOT NULL,
    B3         CHAR(4)         NOT NULL,
    CONSTRAINT T1_PK PRIMARY KEY (K1)
    ) ;

    TABLE T2
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE T2 
    (
    K2        INT             NOT NULL,
    X         CHAR(4)         NOT NULL,
    Y         CHAR(4)         NOT NULL,
    CONSTRAINT T2_PK PRIMARY KEY (K2)
    ) ;

    Pour comprendre un peu le comportement des moteurs relationnels, considérons la modeste requête suivante :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT T1.*
    FROM T1 INNER JOIN T2 ON T1.A1 = T2.X ;

    Les colonnes participant à la jointure sont A1 et X. Si ni l’une ni l’autre ne sont indexées, le SGBD va là aussi balayer complètement une des deux tables et pour chaque ligne lue, balayer complètement l’autre table pour produire un résultat qui vérifie la condition de jointure. Coût de l’opération (en reprenant les volumétries précédentes) :

    30000 X 10000 accès logiques...

    A nouveau ça n’est pas bien fameux... Supposons maintenant que les colonnes A1 et X soient indexées, respectivement par des index T1_A1_AK et T2_X_AK. Supposons encore que le SGBD commence par exploiter la table T1 : en fait, il ne balaie pas la table, mais l’index T1_A1_AK, et pour chaque valeur lue V, le SGBD cherche cette valeur V dans l’index T2_X_AK, mais cette fois-ci par accès direct, il n’y a plus de balayage complet, seulement deux ou trois lectures au plus dans l’index, on a mis le turbo. Coût de l’opération (en étant pessimiste, c'est-à-dire en misant sur 3 plutôt que 2 accès) :

    30000 X 3 accès logiques.

    Ce à quoi il faut ajouter un accès à la table, afin de récupérer les valeurs des autres colonnes (en effet on a codé SELECT T1.*) :

    30000 X 4 accès logiques.

    On a quand même changé d’échelle ! Si l’on observe que l’on n’a besoin en fait que de récupérer la clé K1, alors pour éviter cet accès supplémentaire à la table, les index seront créés au moyen des instructions suivantes :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE UNIQUE INDEX  T1_A1_AK ON T1 (A1, K1) ; 
    CREATE UNIQUE INDEX  T2_X_AK ON T2 (X) ;

    Et le SELECT sera réécrit ainsi :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT T1.K1
    FROM T1 INNER JOIN T2 ON T1.A1 = T2.X ;


    A cette occasion, il faut observer que la taille des enregistrements index étant réduite à pas grand-chose, le nombre d’accès physiques sera beaucoup plus réduit que celui des accès logiques.

    =>

    Merci de nous communiquer la durée de ce modeste SELECT.


    Il est clair que toutes les colonnes participant au SELECT ci-dessous seront soumises au même régime d’indexation, sinon on repart pour des durées infinies :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE UNIQUE INDEX  T1_A2_AK ON T1 (A2, K1) ;
    CREATE UNIQUE INDEX  T1_A3_AK ON T1 (A3, K1) ;
    CREATE UNIQUE INDEX  T1_B1_AK ON T1 (B1, K1) ;
    CREATE UNIQUE INDEX  T1_B2_AK ON T1 (B2, K1) ;
    CREATE UNIQUE INDEX  T1_B3_AK ON T1 (B3, K1) ;
    CREATE UNIQUE INDEX  T2_X_AK ON T2 (X, K2) ;
    CREATE UNIQUE INDEX  T2_Y_AK ON T2 (Y, K2) ;

    Ces index pénalisant les opérations de mise à jour (eux aussi doivent être mis à jour...), une fois le traitement terminé, on aura intérêt à effectuer le DROP des index qui ne serviront pas pour les autres traitements.

    En attendant, il s’agit maintenant de transformer le produit en somme. Les « OR » étant les empêcheurs de tourner en rond, on les remplace par des UNION, en fait des UNION ALL pour gagner encore du temps.

    Voici une requête simulant plus ou moins la vôtre est la suivante :

    Code SQL : 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
    SELECT DISTINCT S1.K1
    FROM 
        (      
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.A1 = T2.X 
         UNION ALL
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.A2 = T2.X 
         UNION ALL 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.A3 = T2.X
        ) AS S1
     
    INNER JOIN
     
        ( 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.B1 = T2.Y 
         UNION ALL 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.B2 = T2.Y 
         UNION ALL 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.B3 = T2.Y 
        ) AS S2
     
    ON S1.K1 = S2.K1 ;

    Du fait de la présence de UNION ALL, Un SGBD normalement constitué concatène les résultats des SELECT élémentaires, d’où l’effet de somme.

    Ainsi, le nombre d’accès logiques pour le du 1er bloc :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT K1 FROM T1 INNER JOIN T2 ON T1.A1 = T2.X 
    UNION ALL
    SELECT K1 FROM T1 INNER JOIN T2 ON T1.A2 = T2.X 
    UNION ALL 
    SELECT K1 FROM T1 INNER JOIN T2 ON T1.A3 = T2.X

    Est de l’ordre de :

    30000 X 3 + 30000 X 3 + 30000 X 3

    Même chose en ce qui concerne le 2e bloc :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT K1 FROM T1 INNER JOIN T2 ON T1.B1 = T2.Y 
         UNION ALL 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.B2 = T2.Y 
         UNION ALL 
          SELECT K1 FROM T1 INNER JOIN T2 ON T1.B3 = T2.Y

    Soit en tout, à la louche (on est loin des 3.10^12 ou des 3.10^15...) :

    54 x 10^4

    Mais, comme on l’a évoqué, avec un nombre d’accès physiques beaucoup plus réduit du fait qu’on récupère seulement les valeurs de la clé K1 au lieu de l’ensemble des lignes.

    A ceci, il faut bien sûr ajouter la consommation résultant de la jointure des deux blocs.

    =>

    Dites-nous si on arrive à des temps de traitement raisonnables (et quels sont-ils) :

    1) Pour le 1er paquet, celui qui précède l’INNER JOIN,

    2) Pour le 2e paquet, celui qui suit l’INNER JOIN,

    3) pour la jointure complète.

    Sinon, on trouvera bien des astuces pour y parvenir.


    Tout SGBD relationnel propose une instruction EXPLAIN permettant de savoir objectivement comment les choses se passent quant à l’utilisation des index et des stratégies mises en œuvre par l’optimiseur pour accéder aux données. Avec ACCES, il existe quelque chose qui s’appelle SHOWPLAN, mais pour ma part je n’ai pas eu l’occasion de m’en servir, peut-être Fabien a-t-il un avis ?


    N.B. Au besoin, la toute 1re ligne de la requête, à savoir SELECT DISTINCT S1.K1 doit pouvoir, sans grand risque, être remplacée par SELECT DISTINCT S1.*, puisque la sélection n’ est effectuée qu’en dernier lieu.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2014
    Messages : 17
    Points : 13
    Points
    13
    Par défaut Un grand merci
    Bonjour,

    Alors j'ai essayé de comprendre et primo je pense avoir compris d'ou venait le 10^15 (plutot pas mal hein !!!! )

    Ensuite, j'ai des petites questions avant de me lancer :

    Premiere chose, ma table PNR_REF_PR_1 est un ALIAS de PNF_REF_PR (Est ce que cela pose problème ?)

    Lors de l'import de mes deux tables je laisse access gérer la clé pirmaire donc K1 est un int généré sur mes enregistrements

    Une proposition :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CREATE UNIQUE INDEX  MagisterV1_LieuDepart ON MagisterV1 (Lieu_Depart, K1) ; 
    CREATE UNIQUE INDEX  MagisterV1_LieuArrivee ON MagisterV1 (Lieu_Arrivee, K1) ;
    CREATE UNIQUE INDEX  PNF_REF_PR_CodeTT0020 ON PNF_REF_PR (Code_TT0020_Localite, Code_TT0020_Chantier) ;
    La suite :

    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
    SELECT DISTINCT S1.K1
    FROM 
        (      
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR ON MAGISTERV1.Lieu_Depart = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier] 
         UNION ALL
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR ON (MAGISTERV1.Lieu_Depart & "-00") = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier]
         UNION ALL 
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR ON (MAGISTERV1.Lieu_Depart & "-BV") = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier]    
         ) AS S1
     
    INNER JOIN
     
        ( 
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR_1 ON MAGISTERV1.Lieu_Arrivee = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier] 
         UNION ALL
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR_1 ON (MAGISTERV1.Lieu_Arrivee & "-00") = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier]
         UNION ALL 
          SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR_1 ON (MAGISTERV1.Lieu_Arrivee & "-BV") = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier]    
        ) AS S2
     
    ON S1.K1 = S2.K1 ;
    Je ne pense pas que ceci marche pour l'instant. Je vous propose un premier round

    Merci pour votre aide

  9. #9
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour niKgir,



    Citation Envoyé par niKgir Voir le message
    Ma table PNR_REF_PR_1 est un ALIAS de PNF_REF_PR (Est-ce que cela pose problème ?)
    Il y aurait plutôt un problème s’il n’y avait pas d’alias, car le SGBD serait incapable de savoir à laquelle des deux instances de PNF_REF_PR une colonne telle que Code_TT0020_Chantier fait référence. Pour équilibrer et éviter les jalousies entre tables (c’est très susceptible une table...), vous pourriez même mettre en oeuvre deux alias.



    Citation Envoyé par niKgir Voir le message
    Lors de l'import de mes deux tables je laisse Access gérer la clé primaire donc K1 est un int généré sur mes enregistrements.
    C’est même un INT double qui est généré (ce dont il faut tenir compte, par exemple si l’on utilise des clés étrangères). Quoi qu’il en soit, les déclarations de tables que j’ai proposées deviennent évidemment :

    TABLE T1
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE TABLE T1 
    (
    K1         AUTOINCREMENT,
    A1         CHAR(4)         NOT NULL,
    A2         CHAR(4)         NOT NULL,
    A3         CHAR(4)         NOT NULL,
    B1         CHAR(4)         NOT NULL,
    B2         CHAR(4)         NOT NULL,
    B3         CHAR(4)         NOT NULL,
    CONSTRAINT T1_PK PRIMARY KEY (K1)
    ) ;

    TABLE T2
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE T2 
    (
    K2        AUTOINCREMENT,
    X         CHAR(4)         NOT NULL,
    Y         CHAR(4)         NOT NULL,
    CONSTRAINT T2_PK PRIMARY KEY (K2)
    ) ;

    Mais, bien entendu, sur le fond ça ne change rien.


    Citation Envoyé par niKgir Voir le message
    Une proposition :

    CREATE UNIQUE INDEX MagisterV1_LieuDepart ON MagisterV1 (Lieu_Depart, K1) ;
    CREATE UNIQUE INDEX MagisterV1_LieuArrivee ON MagisterV1 (Lieu_Arrivee, K1) ;
    CREATE UNIQUE INDEX PNF_REF_PR_CodeTT0020 ON PNF_REF_PR (Code_TT0020_Localite, Code_TT0020_Chantier) ;

    Pour les deux premiers, oui, pour le 3e faut voir : pourriez-vous afficher les CREATE TABLE des deux tables ?


    Citation Envoyé par niKgir Voir le message
    Je ne pense pas que ceci marche pour l'instant. Je vous propose un premier round
    Pour en juger objectivement, partons du principe bien connu que, si un problème est décomposable en problèmes élémentaires, il faut d’abord se pencher sur ceux-ci. Autrement dit, que donne la requête (dont j’ai qualifié de modeste son homologue dans mon précédent message) :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT K1 FROM MagisterV1 INNER JOIN PNR_REF_PR ON MAGISTERV1.Lieu_Depart = PNR_REF_PR.[Code_TT0020_Localite & "-" & Code_TT0020_Chantier]

    Dans le contexte, c’est une étape nécessaire : si ça se traîne, ça sera évidemment encore pire pour la requête plus copieuse...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  10. #10
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour niKgir,


    Quelles sont les nouvelles ?
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  11. #11
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2014
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2014
    Messages : 17
    Points : 13
    Points
    13
    Par défaut news
    Bonjour,

    Au vu de l'urgence du projet j'ai du mettre en place d'autres solutions.

    raison : impossible de créer les "unique index" dans Access j'ai jamais pu trouver la bonne syntaxe...

    Du coup, j'ai contourné le problème de la manière suivante. Un distinct sur mes champs lieu_depart et lieu_arrivee ce qui m'a déjà réduit la base.

    Ensuite j'ai importé les données dans des variables sous VBA dans des tableaux temporaires puis une fois les données associées avec le référentiel.

    J'ai associé ;es données temporaires aux données réels (les fameux 30K enregistrements)

    Puis un gros insert into xD...

    Le traitement est quasi instantané.

    Merci beaucoup pour votre aide mais le contexte a fait que j'ai du déplacer le problème sur quelque chose que je maîtrisais (VBA)

  12. #12
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonjour,


    C'est dommage, il suffisait de copier les CREATE INDEX dans des requêres et exécuter. Mais bon, bonne route, et n'hésitez pas à revenir nous rendre visite...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. [WD17] [Accès natif Mysql]Unicode: plantage requête avec caractère accentué..
    Par Christophe Charron dans le forum WinDev
    Réponses: 4
    Dernier message: 03/03/2013, 16h59
  2. Réponses: 11
    Dernier message: 20/11/2008, 18h08
  3. Réponses: 1
    Dernier message: 20/04/2007, 23h56
  4. [MySQL] Réécriture de requêtes imbriquées en requêtes classiques
    Par erazkan dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 19/04/2007, 13h11
  5. [Oracle 9.1] Plantage SQL+ à cause d'une requête
    Par ftrifiro dans le forum Oracle
    Réponses: 8
    Dernier message: 04/10/2005, 15h08

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