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 :

Récuperation enregistrement le plus récent : Soucis de performance [AC-2010]


Sujet :

Requêtes et SQL.

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2015
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Récuperation enregistrement le plus récent : Soucis de performance
    Bonjour,

    On m'a fourni une base de donnée contenant un table qui se présente sous la forme suivante :

    frefarticle Données (plusieurs colonnes) fdatelivdem (une date)
    1 xxxxx 05/05/2014
    1 xxyxx 01/01/2014
    1 xxyyy 02/08/2015
    2 aaxxx 15/12/2014
    2 zzzuu 02/01/2015

    Pour chaque référence, je ne veux récupérer que les données les plus récentes.
    Soit pour ce exemple :

    frefarticle Données (plusieurs colonnes) fdatelivdem (une date)
    1 xxyyy 02/08/2015
    2 zzzuu 02/01/2015

    J'utilise ensuite ces données pour compléter des données dans un classeur Excel.

    Jusque là, pas de soucis,
    depuis Excel, j'ouvre un recordset avec la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT * FROM  NomTable a WHERE a.fdatelivrdem =
    (SELECT MAX(b.fdatelivrdem) FROM NomTable b WHERE b.frefarticle=a.frefarticle GROUP BY b.frefarticle)
    ORDER BY a.frefarticle
    Le problème ici vient du fait que cette base est vraiment très grande (plus de 140 000 enregistrements) ce qui fait que le temps de traitement est énorme (je ne suis jamais allé jusqu'au bout).

    Y a-t-il un moyen d'optimiser cette requête et/ou un travail en amont à réaliser sur la table, sous access afin de rendre la procédure réalisable ? :/
    J'ai déjà supprimé les champs dont je ne me servais pas et réduit la base au maximum en supprimant les données trop anciennes pour être utiles (Il s'agit d'une copie que l'on m'envoie, je peux lui faire "subir" n'importe quoi sans danger)

    Merci de votre aide

  2. #2
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    As-tu essayé de "Casser" ta requête en 2 ?

    1. reqMaxB : Une requête qui calcule les maxima de B : Code Produit, DateMax
    2. reqMaxA : Une requête qui prend les données de A en jointure sur reqMaxB


    À mon avis cela devrait être plus rapide que de calculer le max à chaque enregistrement.

    Autre solution, faire une requête pour enregistrer les maxima dans une table temporaire et faire la jointure sur la table temporaire.
    Ou utiliser les macros de données (triggers de Access) pour garder une table des maxima au fur et à mesure de l'évolution de B (je ne sais pas si c'est possible).

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  3. #3
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 001
    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 001
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir,

    Par ailleurs, qu’est-ce que cela donne sans le GROUP BY (en principe inutile) ? Les colonnes en cause sont-elles indexées ?
    (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.

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2015
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Merci de m'avoir répondu.
    Bonsoir,

    Par ailleurs, qu’est-ce que cela donne sans le GROUP BY (en principe inutile) ? Les colonnes en cause sont-elles indexées ?
    Si j'enlève le GROUP BY, pas de différence, même temps de traitement, et les colonnes sont bien indexées.

    Bonjour.

    As-tu essayé de "Casser" ta requête en 2 ?

    reqMaxB : Une requête qui calcule les maxima de B : Code Produit, DateMax
    reqMaxA : Une requête qui prend les données de A en jointure sur reqMaxB



    À mon avis cela devrait être plus rapide que de calculer le max à chaque enregistrement.

    Autre solution, faire une requête pour enregistrer les maxima dans une table temporaire et faire la jointure sur la table temporaire.
    Ou utiliser les macros de données (triggers de Access) pour garder une table des maxima au fur et à mesure de l'évolution de B (je ne sais pas si c'est possible).

    A+
    En effet avec une union j'ai un résultat avec un temps d'exécution très raisonnable. J'ai un peu le mauvais réflexe de mettre des sous requêtes partout ><


    Je suis passé par cette requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT DISTINCT *
    FROM  nomTable AS a INNER JOIN 
        (SELECT frefarticle, Max(fdatelivrdem) AS MaxDefdatelivrdem
        FROM  nomTable
        GROUP BY frefarticle)  AS b
    ON (a.fdatelivrdem = b.MaxDefdatelivrdem) AND (a.frefarticle = b.frefarticle)
    ORDER BY a.frefarticle
    (J'utilise le distinct car le cas ou les données sont exactement identiques pour deux enregistrements se produit quelques fois)

    Le temps de traitement étant satisfaisant, je n'ai pas tenté la méthode avec la création d'une table temporaire, je ne pense pas que j'y gagnerais tellement en terme d'efficacité.
    Pour la dernière solution, je ne me suis pas lancé dedans non plus, C'est la première fois que j'ai à utiliser des bases access (Je n'ai fait que du MySQL et de l'Oracle ) et je suis un peu pressé par le temps, l'étude des triggers sous access devra attendre un peu, mais ça m'intéresse tout de même.

    J'en profite pour dire que j'ai énormément gagné en temps de traitement car pour placer les informations obtenues par cette requête dans mon catalogue, sous Excel, j'utilisais la méthode find alors que j'ai un catalogue trié. J'ai donc écrit une fonction pour faire des recherches dichotomiques, en terme de rapidité, forcément, ça change tout... D'ailleurs si il existe un fonction de recherche dichotomique dans les librairies de base en VBA, je ne l'ai pas trouvée :/ Je met ici le code de la mienne des fois que ça serve à quelqu'un, sait-on jamais...

    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
    Public Function rech_dicho(plage As Range, valeurCherchee As Variant) As Range
     
        Dim ligneDebut As Double
        Dim ligneFin As Double
        Dim ligneLue As Double
     
        Set rech_dicho = Nothing
     
        ligneDebut = 1
        ligneFin = plage.Count
     
        If plage.Cells(ligneDebut).Value > valeurCherchee Then
            Set rech_dicho = Nothing
            Exit Function
        End If
     
        If plage.Cells(ligneFin).Value < valeurCherchee Then
            Set rech_dicho = Nothing
            Exit Function
        End If
     
        While ligneDebut <> ligneFin - 1
            ligneLue = Int((ligneFin + ligneDebut) / 2)
            If plage.Cells(ligneLue).Value = valeurCherchee Then
                Set rech_dicho = plage.Cells(ligneLue)
                Exit Function
            End If
     
            If plage.Cells(ligneLue).Value > valeurCherchee Then
                ligneFin = ligneLue
            Else
                ligneDebut = ligneLue
            End If
        Wend
     
        If plage.Cells(ligneDebut).Value = valeurCherchee Then
            Set rech_dicho = plage.Cells(ligneDebut)
        ElseIf plage.Cells(ligneFin).Value = valeurCherchee Then
            Set rech_dicho = plage.Cells(ligneFin)
        End If
     
     
    End Function
    Sur ce je passe tout ça en résolu. Merci à vous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Liste des enregistrements les plus récents
    Par calagan99 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 19/03/2008, 11h39
  2. Réponses: 5
    Dernier message: 25/01/2008, 20h26
  3. Ne conserver que les N enregistrement les plus récents.
    Par gomodo dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/01/2008, 19h46
  4. Trouver l'enregistrement le plus récent
    Par PrinceMaster77 dans le forum Langage SQL
    Réponses: 8
    Dernier message: 19/02/2005, 19h14
  5. recup des enregistrement les plus récents.
    Par julien_guy dans le forum Langage SQL
    Réponses: 8
    Dernier message: 29/06/2004, 11h04

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