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 MySQL Discussion :

Besoin d'optimisation d'une requête


Sujet :

Requêtes MySQL

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Responsable marketing opérationnel
    Inscrit en
    Août 2017
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable marketing opérationnel

    Informations forums :
    Inscription : Août 2017
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Besoin d'optimisation d'une requête
    Bonjour,

    Voici un récap' de la situation

    Table client_t as _t
    clientid | id_client | email | ...
    123rez | i123456 | email@email.fr | ...
    12t845 | i987654 | abc@abc.fr | ...
    f853fr | profil1 | zzz@zzz.fr | ...
    ad857d | i526547 | - | ...


    Table query_reservation_sejour as _a (table contenant les commandes mises à jour via le champ 'statut')
    id_client | id_reservation | statut | event_day | ...
    i123456 | 1234567 | gin | 02-10-2013 | ...
    i123456 | 1234568 | gin | 01-10-2013 | ...
    i123456 | 1234569 | gin | 01-10-2007 | ...



    Table query_reservation_sejour_2 _b (table contenant tous les enregistrements liés à toutes les commandes)
    clientid | id_client | id_reservation | statut | montant_ttc_panier | ...
    123rez | i123456 | 1234567 | gin | 02-10-2013 | 127,53 | ...
    123rez | i123456 | 1234567 | gin | 25-09-2013 | 154,52 | ...
    123rez | i123456 | 1234567 | ein | 01-09-2013 | 154,52 | ...
    123rez | i123456 | 1234568 | gin | 01-10-2013 | 627,83 | ...
    123rez | i123456 | 1234569 | gin | 01-10-2007 | 78,49 | ...

    =========================

    Ma recherche:
    Toutes les commandes passées par des clients (après application filtres sur champ email et id_client) après le 01-10-2012 pour lesquelles le statut prend des valeurs spécifiques.

    Résultat attendu:
    _a.id_reservation | _t.email | _a.event_day | _b.montant_ttc_panier
    1234567 | email@email.fr | 02-10-2013 | 127,53
    1234568 | email@email.fr | 01-10-2013 | 627,83

    Requête à optimiser car temps de traitement trop long:

    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
    SELECT _a.id_reservation, _t.email, _a.event_day, _b.montant_ttc_panier
     
      FROM query_reservation_sejour as _a
      JOIN query_reservation_sejour_2 as _b on _b.id_reservation=_a.id_reservation and _b.event_day=_a.event_day
      JOIN client_t as _t on _b.clientid=_t.id
     
      WHERE (_b.statut = 'gin'
          OR _b.statut = 'ggr'
          OR _b.statut = 'din')
     
      AND _b.event_day > '2012-10-01'
     
      AND _t.id_client NOT REGEXP '^[a-hj-zA-HJ-Z]'
      AND _t.email LIKE '%@%'
      AND _t.email REGEXP '^[a-zA-Z0-9][+a-zA-Z0-9._-]*@[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]*\\.[a-zA-Z]{2,4}$'
     
    GROUP BY _a.id_reservation;
    Merci par avance

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 804
    Points
    30 804
    Par défaut
    Existe-t-il des index sur les tables utilisées dans cette requête ?
    Lesquels ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 893
    Points
    38 893
    Billets dans le blog
    9
    Par défaut
    Bonsoir,

    Le prédicat 'OR' nécessite plusieurs utilisations d'index, si index éligible il y a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      WHERE (_b.statut = 'gin'
          OR _b.statut = 'ggr'
          OR _b.statut = 'din')
    Ce filtre sur la date est probablement non éligible en terme d'index, en tout cas si la table contient des lignes récentes, 2012 c'est déjà vieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        AND _b.event_day > '2012-10-01'
    Le prédicat "NOT" n'est pas SArgAble
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      AND _t.id_client NOT REGEXP '^[a-hj-zA-HJ-Z]'
    Le prédicat like avec "%" en début de chaine de caractères n'est pas SArgAble non plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      AND _t.email LIKE '%@%'
    Et les fonctions de colonne ne le sont pas non plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      AND _t.email REGEXP '^[a-zA-Z0-9][+a-zA-Z0-9._-]*@[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]*\\.[a-zA-Z]{2,4}$'
    Du coup, même si index il y a, peu de chances d'avoir un temps de réponse raisonnable si les tables ont un volume significatif

    Pour les critères chaine de caractères, envisagez une recherche full text, pour la date, sauf si la table est partitionnée par année, peu d'optimisation possible

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 947
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 947
    Points : 5 846
    Points
    5 846
    Par défaut
    Supprimez le GROUP BY.

  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 381
    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 381
    Points : 19 067
    Points
    19 067
    Par défaut
    Salut Edgy13.

    L'analyse d'Escartefigue est tout à fait pertinente, mais en regardant de plus votre message, il y a, a priori, des problèmes de conceptions de votre base de données.

    1) pourquoi mettre dans la même et de surcroit dans la base de données des noms de colonnes très similaire : clientid & id_client.
    Cela va porter à confusion et donc source d'erreur.

    2) vous avez créé un identifiant client (panachage de chiffres et de lettres) qui n'apporte rien sinon que des complications.
    Le mieux aurait été de définir cette colonne avec le type "integer", voire "bigint".

    3) je ne sais pas ce que signifie ce panachage de chiffres et de lettres, mais comme vous faites une recherche dessus, le mieux aurait été de créer une table de catégorie.
    Cette table catégorie aurait une clef étrangère qui pointe sur la table des clients.

    4) qu'est-ce que ce ce schmilblick :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND _t.id_client NOT REGEXP '^[a-hj-zA-HJ-Z]'
    qui ne sert à rien sinon à rendre votre requête inintelligible ?

    Vous vérifier que le premier caractère de votre colonne "id_client", est soit un "i" minuscule ou majuscule ou soit un chiffre ou autre chose.
    Si vous avez besoin de récupérer l'identifiant commençant par un "i", on fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND _t.id_client like 'i'
    De plus, vous avez besoin de ne pas faire de distinction entre les majuscules et les minuscules.
    En principe, en français, on utilise le collate "latin1_general_ci" ou "utf8_general_ci", car CI signifie insensible à la casse.

    5) cette recherche sur les email, ne sert à rien.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    AND _t.email LIKE '%@%'
    AND _t.email REGEXP '^[a-zA-Z0-9][+a-zA-Z0-9._-]*@[a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]*\\.[a-zA-Z]{2,4}$'
    La colonne email est une information et ne peut pas servir à faire des recherches.

    Si c'est pour vérifier la syntaxe de l'adresse email, cela se fait au moment de la saisie de celle-ci pas après.

    6) que signifie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND _b.event_day > '2012-10-01'
    Désirez vous récupérer que les dates du mois de octobre de l'année 2012 ?
    Dans ce cas là, je vous conseille de partitionner vos tables.
    Le fait d'interroger une partition, vous permet de récupérer que les extractions de cette partition.

    Si c'est pour récupérer toutes les lignes allant d'octobre 2012 jusqu'à aujourd'hui, votre test devra balayer toutes les lignes de la tables et donc vos index ne servent à rien.
    Il faudrait plus d'explication sur l'usage de cette date afin de mieux comprendre ce que vous cherchez à sélectionner.

    7) rien de particulier à dire sur les jointures.

    8) il reste alors ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    WHERE (_b.statut = 'gin'
       OR  _b.statut = 'ggr'
       OR  _b.statut = 'din')
    Le mieux serait de faire un union comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select ... from table_1 where col1 = val_1 union
    select ... from table_1 where col1 = val_2 union
    select ... from table_1 where col1 = val_3
    Mais la recherche sera trois fois plus lente qu'une seule extraction.

    En gros, vous devez revoir complètement la structure de votre base de données afin d'améliorer considérablement votre requête.
    Vos index, ne servent à rien !

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

Discussions similaires

  1. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45
  2. Besoin d'aide sur une requête (JOIN + COUNT ?)
    Par PanzerKunst dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/06/2005, 10h29
  3. [DB2] Optimisation d'une requête
    Par ahoyeau dans le forum DB2
    Réponses: 7
    Dernier message: 11/03/2005, 17h54
  4. Besoin d'aide pour une Requête SQL ...
    Par Kokito dans le forum Requêtes
    Réponses: 2
    Dernier message: 07/07/2004, 11h56
  5. besoin d'aide pour une requête
    Par Damien69 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 31/03/2004, 15h38

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