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

SGBD Perl Discussion :

[sgbd] mysql


Sujet :

SGBD Perl

  1. #1
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut [sgbd] mysql
    Bonjours à tous,

    Je voulais avoir une évaluation sur la question suivante :

    Je souhaitais optimiser un programme qui se connecte à une base et efectue de requetes.
    Je voulais savoir si la connexion / déconnexion à une base en Perl prenait beaucoup de temp ou non (Comme le php ou ca ne prend pas beaucoup de temps par exemple ).

    Car mon programme est un serveur chargé d'effectuer les requetes de clients sur une base et j'hésitait soit à faire une connexion au début et la garder tout au long du prog pour effectuer les requetes, soit à connecter / déconnecter à chaque requete.

    Il est évident que la première solution est la plus rapide, mais de combien ? C'est ca la question en fait. Par exemple pour l'éxécution de 100 requetes ?


    merci.

  2. #2
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    C'est lent, un point c'est tout. Sur MySQL c'est pas trop mauvais, sur Pg ça commence à se resentir et sur Oracle c'est horrible.

    La meilleur solution consiste à l'ouvrir une fois au début, et le fermer dans un END block à la fin. C'est fait pour. J'ai des processes qui ouvrent des connexions à des bases qui restent ouverts longtemps. J'en vois un ici qui est ouvert depuis le 7 avril.

  3. #3
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    Et tu sais comment faire pour mon cas ?

    Je veux dire pour garder une connexion établie au début du prog et l'utiliser tout au long de ce dernier ? (Je rappelle que c'est pour le prog C qui appelle le Perl... )
    (Voir ici pour plus de précisions :
    http://www.developpez.net/forums/viewtopic.php?t=340047 )

    merci en tout cas.

    ++

  4. #4
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    C'est assez facile. D'abord il faut s'occuper de ta connexion:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    BEGIN {
        my $db;
        sub db {
            $db = DBI->connect_cached('DBI:dsn', 'user', 'pw') or die $DBI::errstr;
            $db;
        }
        END { $db and $db->disconnect }
    }
    On utilise connect_cached, qui s'occupe de faire la connexion initiale, et chaque fois que tu le demandes, il vérifíe si c'est la première fois, ou si entre temps la base a été rebooté et dans les deux cas il établit une nouvelle connexion. Si tu as déjà établi une connexion avec cette même DSN, User et Pass, il reprend la connexion directement de son cache interne. Ensuite on retourne le handle.

    Le END { ... } est là pour terminer la connexion proprement, quelque soit la manière que le programme choisira de mourir (via exit ou die par exemple). Ensuite tu n'as plus qu'appeller cette routine chaque fois que tu veux un handle à ta base:

    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
     
    # en perl
    my $ss = db()->prepare( 'select count(*) from t1' ) or die "blah: $DBI::errstr\n";
     
    /* en C */
    SV get_db
    {
        dSP;
        int ret;
        SV db_handle;
     
        ENTER;
        SAVETMPS;
        PUSHMARK(SP);
     
        ret = call_pv( "db", G_SCALAR | G_NOARGS | G_EVAL );
        SPAGAIN;
     
        if( ret != 1 ) {
            fprintf( STDERR, "et merde: %d\n", ret );
        }
        db_handle = POPs;
     
        PUTBACK;
        FREETMPS;
        LEAVE;
        return db_handle;
    }
    Enfin le C, je ne suis pas 100% sûr, mais vu que tu potasses le C ça devrait te parler.

  5. #5
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    Pour la partie C, pas de pb, par contre ce que je vois pas trop c'est pour la connexion : si tu as vu les précédent post que j'ai mis, tu dois savoir que je crée un objet connexion dans mon script Perl, puis des objets requete que j'exécute en appellant l'objet connexion pour le lien avec la base.
    Ce que je veux savoir, c'est si je met ton code Përl pour la connexion dans mon objet ou si il faut que je change mes script pour que quand je demande l'éxécution d'une requete sur la base, je tente une connexion (qui si elle a déjà été faite n'est pas refaite) puis l'éxécution de la requete ?

    Je sais pas si j'ai été clair.. ?


    merci en tout cas.

    ++

  6. #6
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    Et sinon, a quoi correspond le '$db' dans la partie END ? Je veux dire qu'est_ce que ca fait ?

  7. #7
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par kij
    Et sinon, a quoi correspond le '$db' dans la partie END ? Je veux dire qu'est_ce que ca fait ?
    En gros, ça s'assure que $db correspond à quelque chose avant de tenter la déconnexion, le 'and' n'étant vrai que si $db est définie.

  8. #8
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    C'esst bon en fait, j'ai juste modifié mon objet Connexion comme suit :
    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
     
    sub new {
        #print "entre dans Connexion\n";
        my $classouref = shift;
        my $class = ref($classouref) || $classouref;
        # vérification des arguments :
        my $nb = @_;
        die "Connexion intérrompue : Connexion::new : arg != 4\n" if ($nb != 4 );
        my($driver, $base, $user, $pwd) = @_;
     
        # tentative d'établissement de la connexion :
      #  my $dbh = DBI->connect("DBI:".$driver.":".$base,$user,$pwd, {RaiseError => 1, AutoCommit => 0 })
        my$dbh = DBI->connect_cached("DBI:".$driver.":".$base,$user,$pwd)
                or die "Connexion a la base impossible pour la raison suivante : ".$DBI::errstr;
        my $self = {};
        $self->{'connexion'}=$dbh;
        bless ($self, $class);
     
        # retourne l'identifiant de connexion brute et non un objet Connexion.
        return $self;
    }
    Je pense que c'est cela que tu me disais ? Sinon dit moi si je me trompe

    merci bien.

    ++

  9. #9
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Non, c'est pas tout a fait ça. Quand tu détruis ton objet, tu ne l'as pas déconnecté avant, et puis, c'est bête de consommer une connexion par objet.

    Il ne faut avoir qu'une seule connexion à la base, partagé par tous les objets de ton programme, ce que j'ai proposé. Au lieu de garder en cache une connexion dans ton objet, tu n'as que faire un appel à db() chaque fois que tu en as besoin dans les methodes de l'objet, et tu auras une connexion toute fraîche.

    En plus, la base sera déconnectée proprement, quelque soit la manière dont le script se termine (modulo un segfault, toujours d'actualité quand on fait du C).

  10. #10
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    Euh.. je comprend encore moins la !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    BEGIN { 
        my $db; 
        sub db { 
            $db = DBI->connect_cached('DBI:dsn', 'user', 'pw') or die $DBI::errstr; 
            $db; 
        } 
     
      ... ici j'éxécute des requetes en utilisant $db ....
     
     
        END { $db and $db->disconnect } 
    }
    Comme ca c'est bon non ?

  11. #11
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    J'avais pas vu que tu avais utilisé connect_cached, donc en effet il n'y a qu'une connexion. Mais je pense que c'est une très mauvaise idée question architecture de copier des dizaine de réferences à cette connexion à droite à gauche. Tu as une connexion, gardes-la dans un seul endroit.

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 171
    Points : 70
    Points
    70
    Par défaut
    Bonjour,

    Puisque vous parlez de ca, dans le cas d'une application web, je suppose qu'en cas d'interrogation d'une base Oracle, on perd du temps aussi.
    Comment faut il gérer les ouvertures et les fermetures a la base?

    Pour le moment, j'ouvre la connexion a chaque debut de page et je la ferme a la fin de chacune. Est ce qu'il y a un moyen d'optimiser cela?
    Est ce qu'il est possible d'ouvrir la connexion a oracle lors de la connexion a l application et de la fermer lorsqu'on la quitte?

    Merci

  13. #13
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Non!

    Laisse tomber l'idée de trainer un $db du début à la fin. Quand tu as besoin de causer avec la base, tu fais un tout petit

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        if (1) {
            my $db = db();
            my $ss = $db->prepare( 'select c1,c2 from t1' );
        }
    voire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        if (1) {
            my $ss = db()->prepare( 'select c1,c2 from t1' );
        }
    Tu te fiches si $db disparaît à la fin du scope, car la prochaine fois que tu appelle db(), tu as une nouvelle copie de la connexion. Et mieux, si la base a été stoppé et starté entre temps, il se reconnecte. Mieux, même si quelqu'un fait $db = 0;, tu t'en fiches, car c'est juste une copie. Tu ne peux pas endommager la connexion.

    Qu'est-ce qu'il y a de plus facile ?

  14. #14
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Pourquoi "if (1)", et pas seulement les accolades pour créer un bloc ?
    La gestion du scope est différente ?

  15. #15
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par linou
    Bonjour,

    Puisque vous parlez de ca, dans le cas d'une application web, je suppose qu'en cas d'interrogation d'une base Oracle, on perd du temps aussi.
    Comment faut il gérer les ouvertures et les fermetures a la base?
    On utilise mod_perl et Apache::DBI, et les processes httpd gardent les connexions ouvertes, pour te les refiler dans ton script de manière transparent. Ce n'est pas si eloigné que ça de mon approche ci-dessus.

  16. #16
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Gamdwin
    Pourquoi "if (1)", et pas seulement les accolades pour créer un bloc ?
    La gestion du scope est différente ?
    Aucune difference. J'ai juste fait ça à la va-vite, histoire de faire semblant d'écrire de vrai code :)

    Les accolades suffisent à créer des blocs de scope

  17. #17
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Citation Envoyé par nematoad
    On utilise mod_perl et Apache:BI, et les processes httpd gardent les connexions ouvertes, pour te les refiler dans ton script de manière transparent. Ce n'est pas si eloigné que ça de mon approche ci-dessus.
    Je suis très intéressé par ce genre de pratique, malheureusement je n'ai pas, et je ne peux pas avoir, mod_perl.

    Y a-t'il un autre moyen de procéder pour éviter de se reconnecter à chaque fois ?

  18. #18
    Membre actif
    Inscrit en
    Février 2005
    Messages
    167
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 167
    Points : 203
    Points
    203
    Par défaut
    Citation Envoyé par Gamdwin
    Y a-t'il un autre moyen de procéder pour éviter de se reconnecter à chaque fois ?
    Le protocole HTTP est "stateless", et par consequence les connexions CGI doivent renouveller la connexion a la base chaque fois. En l'absense de mod_perl ou similaire, il faudrait ecrire un proxy de connexions, en esperant que c'est plus rapide a connecter au proxy que de retablir une connexion.

    Franchement ca me parait un peu galere...

  19. #19
    Membre actif Avatar de Gamdwin
    Inscrit en
    Avril 2005
    Messages
    186
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 186
    Points : 207
    Points
    207
    Par défaut
    Clair.

    Je vais en rester à mes connexions dans chaque script.

  20. #20
    kij
    kij est déconnecté
    Membre habitué
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    362
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 362
    Points : 157
    Points
    157
    Par défaut
    ok,
    merci bien les gars, c'est les explications qu'il me fallait.

    ++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [SGBD] [MYSQL/PHP]Erreur de connexion à la DB
    Par Oufti dans le forum Installation
    Réponses: 4
    Dernier message: 27/12/2005, 08h37
  2. [SGBD] mysql+php+recherche+jointure
    Par nizar05 dans le forum Requêtes
    Réponses: 6
    Dernier message: 09/12/2005, 12h10
  3. [SGBD] MySQL/MySQLi
    Par Tizard dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 05/12/2005, 10h51
  4. [SGBD] MySQL:Probleme lorsque je evux afficher des nombres
    Par pierrot10 dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 16/10/2005, 00h59

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