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 :

Optimisation Requete SQL avec grosse table


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2012
    Messages : 54
    Par défaut Optimisation Requete SQL avec grosse table
    Bonjour à tous,

    j'ai une requete SQL sous Mysql sur une grosse table de prés de 10 millions de lignes. ma requete est constituée de 3 union, entre des requetes du type:

    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
    (SELECT distinct
        DATE_FORMAT(CP.Dateofanalysis,'%M %Y') AS Period,
        IF(CAST(DATE_FORMAT(CP.Dateofanalysis,'%m') AS CHAR)>3,CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis,'%Y') AS CHAR),'-',CAST(DATE_FORMAT(CP.Dateofanalysis,'%Y') AS CHAR)+1),CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis,'%Y') AS CHAR)-1,'-',CAST(DATE_FORMAT(CP.Dateofanalysis,'%Y') AS CHAR))) AS FiscalYearInternal,
        CP.Facility,
        CP.Traded_Manufactured,
        0 AS Horizon,
         CP.OrderedLastMonths AS NbLines,
        CP.OrderToDelivery AS PlanningTimeFence,
        CP.Company,
        CP.Division,
        CP.FTActivityCode,
        CP.FTActivityName,
        CP.Warehouse,
        CP.WarehouseName,
        CP.Item,
        CP.ItemDescription,
        CP.AchievementGroup,
        CP.AchievementFacility
     
     
    FROM
        Big_table
    WHERE CP.Traded_Manufactured IS NOT NULL
    AND CP.OrderedLastMonths=1
    AND CP.DayInMonth =1
    )
    Cette requete prend beaucoup de temps à s'executer (surtout qu'il y'a une union de 4 requêtes similaires, il n'y a que les conditions de IF qui changent, les champs extraits sont les memes).

    Pouvez-vous m'aider à optimiser cette requête ?

    Je vous remercie d'avance

    macsigarev

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    Bonjour,

    s'il n' y a que le IF qui change alors il vous faut déporter cette opération de mise en page côté applicatif.

    Ca vous permettra de gagner 3 table scan (ou index).

    Ensuite vérifiez que vous avez bien un index (s'il l'utilise) sur le couple :
    DayInMonth, OrderedLastMonths, Traded_Manufactured

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2012
    Messages : 54
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Bonjour,

    s'il n' y a que le IF qui change alors il vous faut déporter cette opération de mise en page côté applicatif.

    Ca vous permettra de gagner 3 table scan (ou index).

    Ensuite vérifiez que vous avez bien un index (s'il l'utilise) sur le couple :
    DayInMonth, OrderedLastMonths, Traded_Manufactured

    Merci, en fait j'ai pas bien compris quand vous dites coté applicatif, car c'est une extraction à partir d'un ERP.

    De plus, il existe bien des index sur les 3 champs que vous avez spécifié:

    Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type
    F_KPI_Customer_Performance 0 PRIMARY 1 Company A 17 BTREE
    F_KPI_Customer_Performance 0 PRIMARY 2 OrderNumber A 17 BTREE
    F_KPI_Customer_Performance 0 PRIMARY 3 OrderLineNumber A 17 BTREE
    F_KPI_Customer_Performance 0 PRIMARY 4 OrderLineSuffix A 17 BTREE
    F_KPI_Customer_Performance 0 PRIMARY 5 Upload_Date A 8745080 BTREE
    F_KPI_Customer_Performance 1 Index1 1 Company A 17 BTREE
    F_KPI_Customer_Performance 1 Index1 2 Division A 17 YES BTREE
    F_KPI_Customer_Performance 1 Index1 3 Facility A 17 BTREE
    F_KPI_Customer_Performance 1 Index1 4 DayInMonth A 17 YES BTREE
    F_KPI_Customer_Performance 1 Index1 5 DayInWeek A 17 YES BTREE
    F_KPI_Customer_Performance 1 Index1 6 LastUpdateRecords A 17 YES BTREE
    F_KPI_Customer_Performance 1 Index1 7 OrderNumber A 8745080 BTREE
    F_KPI_Customer_Performance 1 Index1 8 OrderLineSuffix A 8745080 BTREE

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    postez la requête en entiere

  5. #5
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IF(CAST(DATE_FORMAT(CP.Dateofanalysis,'%m') AS CHAR)>3
    CASTer en CHAR et demander de comparer à un chiffre, bizarre !

    Si je comprends le sens de la formule, votre condition vérifie si le mois est supérieur à 3. Pourquoi ne pas directement utiliser EXTRACT ( MONTH FROM CP.Dateofanalysis) (en SQL standard) ou bien plus simplement MONTH(CP.Dateofanalysis) (en MySQL) au lieu du CAST ?

    Principe à appliquer sur l'ensemble de la ligne de code.
    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
    IF
    (
    	MONTH(CP.Dateofanalysis) > 3,
    	CONCAT
    	(
    		YEAR(CP.Dateofanalysis),
    		'-',
    		YEAR(CP.Dateofanalysis) + 1
    	),
    	CONCAT
    	(
    		YEAR(CP.Dateofanalysis) - 1,
    		'-',
    		YEAR(CP.Dateofanalysis)
    	)
    ) AS FiscalYearInternal
    On peut avoir un aperçu des différents IF ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2012
    Messages : 54
    Par défaut
    Citation Envoyé par CinePhil Voir le message
    CASTer en CHAR et demander de comparer à un chiffre, bizarre !

    Si je comprends le sens de la formule, votre condition vérifie si le mois est supérieur à 3. Pourquoi ne pas directement utiliser EXTRACT ( MONTH FROM CP.Dateofanalysis) (en SQL standard) ou bien plus simplement MONTH(CP.Dateofanalysis) (en MySQL) au lieu du CAST ?

    Principe à appliquer sur l'ensemble de la ligne de code.
    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
    IF
    (
    	MONTH(CP.Dateofanalysis) > 3,
    	CONCAT
    	(
    		YEAR(CP.Dateofanalysis),
    		'-',
    		YEAR(CP.Dateofanalysis) + 1
    	),
    	CONCAT
    	(
    		YEAR(CP.Dateofanalysis) - 1,
    		'-',
    		YEAR(CP.Dateofanalysis)
    	)
    ) AS FiscalYearInternal
    On peut avoir un aperçu des différents IF ?
    Merci pour la réponse, j'ai appliqué ce que vous avez dit à la 1ere portion de SELECT de ma requete globale et les performances ne ce sont pas amérliorées, voici le code globale de ma requete:


    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
    (SELECT  DISTINCT 
            DATE_FORMAT(CP.Dateofanalysis, '%M %Y') AS Period,
            IF(
               CAST(DATE_FORMAT(CP.Dateofanalysis, '%m') AS CHAR) > 3,
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR),
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) + 1),
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) - 1,
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR)))
               AS FiscalYearInternal,
            CP.Facility,
            CP.Traded_Manufactured,
            0 AS Horizon,
     
            CP.OrderedLastMonths AS NbLines,
            CP.OrderToDelivery AS PlanningTimeFence,
     
            CP.Company,
            CP.Division,
            CP.FTActivityCode,
            CP.FTActivityName,
            CP.Warehouse,
            CP.WarehouseName,
            CP.Item,
            CP.ItemDescription,
            CP.AchievementGroup,
            CP.AchievementFacility
       FROM global_table
      WHERE     CP.Traded_Manufactured IS NOT NULL
            AND CP.OrderedLastMonths = 1
            AND CP.DayInMonth = 1) 
    UNION
    /* Last 12 months current period */
    (SELECT  DISTINCT 
            DATE_FORMAT(CP.Dateofanalysis, '%M %Y') AS Period,
            IF(
               CAST(DATE_FORMAT(CP.Dateofanalysis, '%m') AS CHAR) > 3,
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR),
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) + 1),
               CONCAT(
                  CAST(
                     DATE_FORMAT(CP.InternalRequestedDeliveryDate, '%Y') AS CHAR)
                  - 1,
                  '-',
                  CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR)))
               AS FiscalYearInternal,
            CP.Facility,
            CP.Traded_Manufactured,
            0 AS Horizon,
     
            CP.OrderedLastMonths AS NbLines,
            CP.OrderToDelivery AS PlanningTimeFence,
     
            CP.Company,
            CP.Division,
            CP.FTActivityCode,
            CP.FTActivityName,
            CP.Warehouse,
            CP.WarehouseName,
            CP.Item,
            CP.ItemDescription,
            CP.AchievementGroup,
            CP.AchievementFacility
       FROM global_table
      WHERE     CP.Traded_Manufactured IS NOT NULL
            AND CP.OrderedLastMonths = 1
            AND CP.LastUpdateRecords = 1
            AND CP.DayInMonth != 1) 
    UNION
     
    (SELECT  DISTINCT 
            DATE_FORMAT(CP.Dateofanalysis, '%M %Y') AS Period,
            IF(
               CAST(DATE_FORMAT(CP.Dateofanalysis, '%m') AS CHAR) > 3,
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR),
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) + 1),
               CONCAT(
                  CAST(
                     DATE_FORMAT(CP.InternalRequestedDeliveryDate, '%Y') AS CHAR)
                  - 1,
                  '-',
                  CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR)))
               AS FiscalYearInternal,
            CP.Facility,
            CP.Traded_Manufactured,
            1 AS Horizon,
     
            CP.OrderedLastMonth AS NbLines,
            CP.OrderToDelivery AS PlanningTimeFence,
            /* Fields for drill-through details */
            CP.Company,
            CP.Division,
            CP.FTActivityCode,
            CP.FTActivityName,
            CP.Warehouse,
            CP.WarehouseName,
            CP.Item,
            CP.ItemDescription,
            CP.AchievementGroup,
            CP.AchievementFacility
       FROM global_table
      WHERE     CP.Traded_Manufactured IS NOT NULL
            AND CP.OrderedLastMonth = 1
            AND CP.DayInMonth = 1) 
    UNION
     
    (SELECT  DISTINCT 
            DATE_FORMAT(CP.Dateofanalysis, '%M %Y') AS Period,
            IF(
               CAST(DATE_FORMAT(CP.Dateofanalysis, '%m') AS CHAR) > 3,
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR),
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) + 1),
               CONCAT(CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR) - 1,
                      '-',
                      CAST(DATE_FORMAT(CP.Dateofanalysis, '%Y') AS CHAR)))
               AS FiscalYearInternal,
            CP.Facility,
            CP.Traded_Manufactured,
            1 AS Horizon,
     
            CP.OrderedLastMonth AS NbLines,
            CP.OrderToDelivery AS PlanningTimeFence,
     
            CP.Company,
            CP.Division,
            CP.FTActivityCode,
            CP.FTActivityName,
            CP.Warehouse,
            CP.WarehouseName,
            CP.Item,
            CP.ItemDescription,
            CP.AchievementGroup,
            CP.AchievementFacility
       FROM global_table
      WHERE     CP.Traded_Manufactured IS NOT NULL
            AND CP.OrderedLastMonth = 1
            AND CP.LastUpdateRecords = 1
            AND CP.DayInMonth != 1)

  7. #7
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Par défaut
    - Est-ce normal d'avoir des CP.OrderedLastMonths et des CP.OrderedLastMonth ?

    - Je ne vois pas d'index sur les OrderedLastMonthX et Traded_Manufactured

    - J'ai l'impression que InternalRequestedDeliveryDate sort du chapeau.

    - Il y a FROM global_table au lieu de probablement FROM Customer_Performance AS CP. Le fait de modifier ta requête ne nous aide pas à la simplifier.

    - Combien d'enregistrements retourne chaque requête ?

  8. #8
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2012
    Messages : 54
    Par défaut
    Citation Envoyé par Fred_34 Voir le message
    - Est-ce normal d'avoir des CP.OrderedLastMonths et des CP.OrderedLastMonth ?

    oui c'est normal, il y'a un champs pour LES mois précédents et un champs pour LE mois précédent.

    - Je ne vois pas d'index sur les OrderedLastMonthX et Traded_Manufactured

    Pourtant j'ai bien crée les index sur ces champs!

    - J'ai l'impression que InternalRequestedDeliveryDate sort du chapeau.

    Non il est bien à sa place, en fait c'est également une condition de test sur 2 des requetes.

    - Il y a FROM global_table au lieu de probablement FROM Customer_Performance AS CP. Le fait de modifier ta requête ne nous aide pas à la simplifier.

    Désolé c'est la même table qui est interrogée dans toutes les requetes.


    - Combien d'enregistrements retourne chaque requête ?
    Prés de 9 millions environ

  9. #9
    Membre émérite
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Par défaut
    Citation Envoyé par macsigarev Voir le message
    Prés de 9 millions environ
    Quel peut bien être l’intérêt d'une requête qui retourne 9 millions d'enregistrements ?

Discussions similaires

  1. [MySQL] Requete SQL avec 2 tables et condition de date+somme
    Par lounou dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 15/11/2012, 17h43
  2. SSIS - Requete sql avec nom de table variable
    Par IcedLand dans le forum Développement
    Réponses: 3
    Dernier message: 03/12/2007, 11h55
  3. SSIS - Requete sql avec nom de table variable
    Par IcedLand dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 03/12/2007, 11h55
  4. Réponses: 5
    Dernier message: 03/09/2007, 13h52
  5. Requete SQL avec NOM de champs et de table dynamique
    Par _stef_ffff_f34 dans le forum Bases de données
    Réponses: 4
    Dernier message: 15/05/2006, 13h28

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