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 :

Requête hyper longue


Sujet :

Requêtes MySQL

  1. #1
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut Requête hyper longue
    J'ai une requête qui tourne depuis samedi matin !
    Contexte :
    A partir de 2 tables sources :
    - veaux (53 millions de lignes)
    - bovins (35 millions de lignes)
    J'ai d'abord importé dans une nouvelle base les veaux et la requête en question est censée ajouter à la nouvelle table les bovins qui ne sont pas déjà référencés parmi les veaux.
    Il s'agit donc d'une requête INSERT avec une jointure entre une table temporaire issue de l'extraction de la nouvelle table (les veaux) et la table source des bovins.
    Le volume à traiter est très gros sur un portable récent avec 2 Go de RAM.
    Le processus MySQLd utilise 50% du processeur (double coeur) donc il semble tourner à plein régime.

    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
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    INSERT INTO bdni2.bovins(B_NUM_NAT, B_SEXE, B_DAT_NAISS, B_DAT_PREM_VELAGE, B_FK_IND_PAYS, 
        B_FK_IND_PAYS_NAISS, B_FK_IND_RACE, B_FK_COD_TEMOIN_NAISS)
    SELECT b.NUM_NAT, 
        CASE 
            WHEN b.SEXE = '' THEN NULL 
            ELSE b.SEXE 
        END, 
        b.DATE_NAISS, b.DATE_PREM_VELAGE, p1.P_IND_PAYS,
        CASE 
            WHEN b.COD_PAYS_NAISS = '' THEN NULL 
            ELSE p2.P_IND_PAYS 
        END, 
        CASE 
            WHEN b.TYP_RACE = '' THEN NULL 
            ELSE r.R_IND_RACE 
        END, 
        b.TEMOIN_NAISS
    FROM bdni.bovins b
    INNER JOIN bdni2.pays p1 ON b.COD_PAYS = p1.P_COD_PAYS
    LEFT JOIN bdni2.pays p2 ON b.COD_PAYS_NAISS = p2.P_COD_PAYS
    LEFT JOIN bdni2.races r ON b.TYP_RACE = r.R_TYP_RACE
    WHERE CONCAT(b.COD_PAYS, '@', b.NUM_NAT) NOT IN (
        SELECT CONCAT(P_COD_PAYS, '@', B_NUM_NAT)
        FROM bdni2.bovins2
    )
    La table des pays n'en contient que 18 et la table des races 63.

    Est-ce que j'attends la fin de la requête ou bien celle-ci est-elle en train de tourner en boucle pour finalement ne donner aucun résultat ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

  2. #2
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 903
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 903
    Points : 6 027
    Points
    6 027
    Par défaut
    Si je peux me permettre: oh la vache

    Bref, il aurait fallu faire un EXPLAIN de ta requête afin de vérifier la pertinence des index déclarés.

    Tu as testé sur un échantillon cette requête ?
    "Il n'y a pas de bonnes réponses à une mauvaise question." (M. Godet)
    -----------------------
    Pensez à cloturer votre sujet - Aucune réponse aux sollicitations techniques par MP
    Usus magister est optimus

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    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 799
    Points : 34 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    J'ai fini par arrêter la requête qui tournait toujours hier soir...
    J'ai fait un EXPLAIN du SELECT source de l'INSERT et j'ai constaté qu'à cause du CONCAT, les index de la table bdni2.bovins2 n'étaient pas utilisés.
    J'ai modifié ma requête avec une jointure et une condition et l'EXPLAIN est beaucoup plus avantageux. Je viens de la lancer, on va voir combien de temps elle prend.
    Voici la nouvelle 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
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    INSERT INTO bdni2.bovins(B_NUM_NAT, B_SEXE, B_DAT_NAISS, B_DAT_PREM_VELAGE, B_FK_IND_PAYS, 
        B_FK_IND_PAYS_NAISS, B_FK_IND_RACE, B_FK_COD_TEMOIN_NAISS)
    SELECT b.NUM_NAT, 
        CASE 
            WHEN b.SEXE = '' THEN NULL 
            ELSE b.SEXE 
        END, 
        b.DATE_NAISS, b.DATE_PREM_VELAGE, p1.P_IND_PAYS,
        CASE 
            WHEN b.COD_PAYS_NAISS = '' THEN NULL 
            ELSE p2.P_IND_PAYS 
        END, 
        CASE 
            WHEN b.TYP_RACE = '' THEN NULL 
            ELSE r.R_IND_RACE 
        END, 
        b.TEMOIN_NAISS
    FROM bdni.bovins b
    INNER JOIN bdni2.pays p1 ON b.COD_PAYS = p1.P_COD_PAYS
    LEFT JOIN bdni2.pays p2 ON b.COD_PAYS_NAISS = p2.P_COD_PAYS
    LEFT JOIN bdni2.races r ON b.TYP_RACE = r.R_TYP_RACE
    LEFT JOIN bdni2.bovins2 b2 ON b.COD_PAYS = b2.P_COD_PAYS AND b.NUM_NAT = b2.B_NUM_NAT
    WHERE b2.B_NUM_NAT IS NULL
    Edit : Requête exécutée en 3 269 secondes, soit moins d'une heure, pour 8 millions de lignes insérées ! C'est quand même beaucoup mieux ! J'avais aussi préalablement désactivé les index dans la table cible de l'insertion.
    Qu'est-ce qui m'a pris de vouloir faire ça avec un CONCAT et un NOT IN alors que j'avais déjà fait la même chose avec une jointure ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    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 !

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/05/2007, 10h10
  2. Requête très longue à éxécuter
    Par pisoka000 dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/05/2007, 11h31
  3. [Requête] Requête trop longue
    Par Ithilien dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 08/01/2007, 10h58
  4. [MySQL] Requête trop longue ?
    Par Thomas1434 dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 24/03/2006, 21h55
  5. Réponses: 4
    Dernier message: 09/12/2005, 08h25

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