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

SQL Procédural MySQL Discussion :

Gros Pb de perf sur une procédure stockée


Sujet :

SQL Procédural MySQL

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 70
    Points : 73
    Points
    73
    Par défaut Gros Pb de perf sur une procédure stockée
    Bonjour,

    J'ai un problème avec une procédure stockée, qui au final me semble être lente lente qu'un traitement en php + mysql...

    Je dois lancer l'import d'un gros fichier d'annonces immobilières (environ 80 000 annonces), avec quelques opérations sur chaque annonce (genre : si c'est une nouvelle annonce, j'insère juste l'annonce dans la base, par contre si c'est une mise à jour, je sauvegarde les modifs dans une table d'historique).

    Pour améliorer les performances, je commence par stocker toutes les annonces à scanner dans une table temporaire. Après, ma procédure stockée parcourt la table temporaire et traite chaque enregistrement.

    Mon 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
    17
    18
    19
    20
    21
     
    DROP PROCEDURE IF EXISTS proapart.traite_annonces_from_fichier $$
    CREATE PROCEDURE proapart.traite_annonces_from_fichier(
        IN des_param_de_config TYPEPARAM
    )
    BEGIN
        DECLARE done INT DEFAULT 0;
        DECLARE d_autres_variables_necesaires_au_traitement TYPEVARIABLE;
            DECLARE cursor_annonces CURSOR
            FOR SELECT
                table_temp.mes_champs_a_recuperer
            FROM table_temp;
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
        OPEN cursor_annonces;
        REPEAT
            FETCH cursor_annonces INTO mes_var_utiles_au_traitement;
            -- Mes tests et mes traitements
        UNTIL done END REPEAT;
        CLOSE cursor_annonces;
    END $$
    DELIMITER ;
    Mon traitement dure presque 2 heures quand je le lance. Quand il ne fait pas planter le serveur mysql (sous windows) au bout de 5000 enregistrements.
    C'est dû à quoi d'après vous ?
    Est-ce c'est que Mysql n'apprécie pas que je lui envoie 80 000 enregistrements dans le cu(rseur) ?

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 70
    Points : 73
    Points
    73
    Par défaut
    Désolé de faire du Up, mais personne n'a une idée ?

  3. #3
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Salut,

    Ta table temporaire est-elle indexée ? Elle fait quelle taille ?
    Regarde peut-être du côté du moteur HEAP.

    Plutôt que de passer par une table temporaire, tu pourrais aussi réaliser les insertions/modifications d'un bloc et utiliser un trigger pour mettre à jour la table d'historique...

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 70
    Points : 73
    Points
    73
    Par défaut
    Citation Envoyé par Maximilian
    Ta table temporaire est-elle indexée ? Elle fait quelle taille ?
    Non, c'est vrai qu'elle n'est pas indéxée. Et c'est vrai qu'elle est en InnoDb, je vais voir à changer ça. Au niveau de la taille, elle a autant d'enregistrements qu'il y a d'annonces, soit 80 000. Ca fait dans les 50/100 Mo.

    En fait jusqu'ici j'y accordais pas énormément d'importance, je pensais que c'était pas si important.

    Mais parce que j'ai un doute, là sur les curseurs.
    Une fois que la sélection est faite et chargée dans le curseur (au début, lors de la déclaration), est-ce que la liste des résultats est chargée dans une grosse variable en mémoire ?
    C'est ce que je pensais jusqu'ici, c'est pour ça que je m'embêtais pas trop avec l'optimisation de la table temporaire.

    Mais si c'est juste un index qui pointe vers les bons enregistrements, du coup là oui, faut que je l'optimise beaucoup plus ma table.
    En même temps je suis con parfois, ça s'appelle un curseur, donc logiquement ça doit être ça.

    Je vais ajouter des indexs et tester le format HEAP. Mais j'ai juste une crainte : mes erreures de plantage, c'est déjà du genre "Out of memory Needed 1633644136 bytes" (sur mon serveur de dev qui a 1Go de RAM, celui de prod a bien plus). Alors une table temporaire directement stockée dans la RAM, ça risque pas d'empirer mes affaires ?

    Je vais voir ce que ça donne.

    J'essaierai les triggers éventuelement après, ça me demande des modifications de code plus importantes.


    En tous cas merci. Parce que là, livrer un produit qui rame autant (quand il ne plante pas) ça ne me plait pas trop ; on peut pas dire que ça me laisse confiant face aux éventuelles montées en charge futures.

    Là j'ai déjà, plus de pistes à suivre.

  5. #5
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Je ne connais pas du tout l'implémentation des curseurs mais j'imagine que tout le résultat n'est pas mis en mémoire dès le début, ou alors bonjour l'engorgement...

    Si j'ai bien compris ta problématique, utiliser un trigger devrait permettre de se passer de SP et de table temporaire et de se reposer uniquement sur les tables de base et leurs index.
    Autant d'éléments intermédiaires lourds zappés pour plus de performance.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 70
    Points : 73
    Points
    73
    Par défaut
    Après quelque tests, finalement j'ai remonté mes manches et tout passé en triggers.

    Adieu tables temporaires et grosses procédures stockées, maintenant j'ai un simple fichier CSV que je traite ligne à ligne, avec un trigger sur l'update.

    Les allers-retours Php / Mysql pour chaque enregistrement me faisaient peur pour les performances, mais au final c'est plus rapide qu'avant (25 % plus rapide).
    Et surtout je suis plus tranquille, ça résoud mes problèmes de mémoire et de stabilité : alors qu'avant ça plantait au bout de 10 minutes, là j'arrive à en lancer plusieurs, de mes gros traitements, ça passe à l'aise.

    Bon, je continue à trouver que 1h30 c'est un peu long... mais comme de toutes façons ca se passera la nuit et que le site n'est pas bloqué, je me remettrai à l'optimisation un peu plus tard.

    Merci !

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

Discussions similaires

  1. Problème sur une procédure stockée
    Par jolio2006 dans le forum PL/SQL
    Réponses: 6
    Dernier message: 17/11/2008, 18h55
  2. [LINQ] Association sur une procédure stockée
    Par RaelRiaK dans le forum Général Dotnet
    Réponses: 1
    Dernier message: 11/06/2008, 14h50
  3. Est il possible de faire un cursor sur une procédure stocké ?
    Par berceker united dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 03/09/2007, 16h47
  4. Aide sur une Procédure stockée
    Par NicoNGRI dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 10/12/2006, 00h48
  5. Réponses: 4
    Dernier message: 14/06/2004, 16h18

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