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

Composants VCL Delphi Discussion :

delphi et ado


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut delphi et ado
    Quelques trucs pour optimiser la vistesse d'une connexion ou requête avec ADO? (curseur,mode,etc).

    J'ai lu que : Utiliser le record set sur un adoquery optimise la vitesse de lecture.

    L'utilisation de DisableControls sur un adoquery fait de même.

    Merci pour vos conseil.

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    DisableControls fonctionne pour tout DataSet c'est un peu l'équivalent du BeginUpdate d'un TStrings, on peut modifier le DataSet, se déplacer sans que cela fasse réagir les DBGrid ou autre DBControl, cela fait gagner beaucoup de temps

    Ensuite, pour l'histoire du RecordSet, je ne sais pas, mais tout dépend ce que tu veux faire, mieux vaut éviter les Edit\Post en privilégiant des UPDATE
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Merci beaucoup pour votre réponse,

    Sinon, mode, curseur ou autres?

    Toutes les méthodes pour optimiser au maximum ADO sont acceptées

  4. #4
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Si vraiment tu veux optimiser les performances au maximum, n'utilise pas ADO !
    Utilise directement OLEDB à la place. J'ai un tuto en cours de rédaction sur le sujet.
    Par contre c'est beaucoup plus complexe qu'ADO.

    Pour rester avec ADO, si tu veux optimiser au mieux, il faut comprendre le fonctionnement :
    - D'abord tu as OLEDB qui effectue tous les accès à la base (avec les interfaces IRowSet, ICommand, IDBSession...).
    - Puis, tu as ADO qui encapsule OLEDB en te fournissant une interface simplifiée (RecordSet à la place de IRowSet).
    - Par dessus ADO, tu as la couche dbGO de Delphi (TADOQuery qui spécialise TADODataSet qui lui même spécialise TDataset).

    OLEDB te retourne les données dans leur type natif et fonctionne en te remplissant des buffers avec les données des lignes complètes (ou ce que tu veux).
    Par dessus, RecordSet lit ce buffer et le convertit pour que tu puisse lire chaque champ sous la forme d'un Variant.
    Enfin, le TDataSet et dérivés vont reconvertir ces variants dans les types de données que tu utilises réellement.
    En plus chaque fois que tu changes de ligne dans le DataSet, ce dernier va déclencher tout une série d'événements (BeforeScroll, AfterScroll, DataChange...) pour que les composants liés se mettent à jour en fonction du nouvel enregistrement actif (en particulier pour qu'ils se redessinent).

    Au final, les performances peuvent facillement être divisées par 4 entre OLEDB et dbGO (temps d'ouverture d'une requête simple + temps de lecture de tous les enregistrements).

    Utiliser DisableControls/EnableControls permet de stopper le déclenchement des événements du Dataset pendant le parcours du jeu de résultat et donc d'éviter un énorme gaspillage de temps.

    Travailler directement avec le RecordSet d'ADO te permet de t'affranchir de la gestion additionnel de dbGO et donc d'améliorer les performances. Mais tu subit toujours la dégradation des performances provoquée par la couche ADO.

    Pour ce qui est des options curseurs et autres, tu es sensé obtenir les performances optimales si tu ouvres un curseur en mode FAST FORWARD ONLY. C'est à dire un curseur client unidirectionnel en lecture seul.
    Concrêtement, il suffit de ne pas utiliser TADOQuery, ni TADOCommand pour exécuter une requête SQL, et d'utiliser à la place la méthode Execute directement sur la connexion. Cette dernière est déjà spécialement optimisée pour ne retourner que ce type de curseur (attention, tu n'as pas le droit d'exécuter une deuxième requête de cette façon tant que tu n'as fermé la précédente).

    Autre remarque, contrairement à ce qu'on peut lire un peu partout, ne prepare pas explicitement les requêtes SQL avant de les exécuter :
    - Préparer une requête engendre un temps de préparation addionnel qui ne pourra être rentabilisé que si tu exécutes la même Query au minimum trois fois.
    - Sur certains SGBD (SQL Server nottament), préparer les requêtes ne sert tout simplement à rien (si ce n'est à perdre du temps). Le SGBD est capable de garder les plans d'exécution en cache tout seul, sans qu'il soit nécessaire de préparer les requêtes, y compris avec des requêtes non paramétrées.


    Pour ce qui concerne la vitesse de connexion :
    J'ai bien peur qu'il n'y ait pas grand chose à faire. Le temps de connexion dépend avant tout du serveur.
    Selon la façon dont tu travailles, tu peux cependant essayer d'utiliser un pool de connexion.
    Si tu passes ton temps à ouvrir et fermer des connexions (genre tu ouvres une nouvelle connexion à chaque exécution de requête, pour la fermer dès que la requête est terminée), avoir un pool de connexion permet de ne pas fermer réellement la connexion, mais de la recycler dans le pool. De cette façon, lors de l'ouverture de la prochaine connexion, tu récupère une connexion déjà ouverte, donc c'est beaucoup plus rapide !
    La gestion du pool de connexion est gérée automatiquement par ADO (en fait, un service de OLEDB) si tu utilise toujours la même chaîne de connexion.
    Cependant, le pool ne reste actif que si tu possèdes toujours au moins une connexion active, ou que tu concerves une référence sur l'interface IDataInitialize si je me souviens bien.
    Hors avec dbGO, tu n'as pas la main sur IDataInitialize. Donc j'ai peur que le pool ne soit détruit chaque fois que tu fermeras la dernière connexion dans ton appli...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Merci pour les précieux conseils, j'en prend note ...

    Seulement,

    attention, tu n'as pas le droit d'exécuter une deuxième requête de cette façon tant que tu n'as fermé la précédente
    Je devrai fermer la connection à la base de donnée avant d'executer une autre requête sql? Si oui je ne crois pas que cela sera optimal de se reconnecter à chaque requêtes, surtout lors d'INSERT successif.

    Merci de m'éclairer.

  6. #6
    Membre Expert

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Par défaut
    Non, c'est la requête que tu dois fermer, pas la connection :

    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
     
    var
      cnt : Connection_;
      res : recordset;
      nb : OleVariant;
    begin
      ... // Il faut initialiser la connexion dans cnt et l'ouvrir ...
      res := cnt.Execute('select * from Table1', nb, adOptionUnspecified);
      try
         ....
      finally
        res.Close; // Il faut fermer le recordset avant de pouvoir réappeler Execute.
        res := nil; // Attention, res := nil ne ferme pas le recordset automatiquement, il faut appeler res.Close explicitement.
      end;
      res := cnt.Execute('select * from Table2', nb, adOptionUnspecified);
    Si tu exécutes la deuxième requête sans avoir fermée le premier recordset, ADO va automatiquement ouvrir une deuxième connexion en douce... (ce qui peut être gênant si les deux requêtes faisaient parti d'une même transaction !).

    Tiens, je suis en train de penser que tout ça c'est pour SQL Server. Je ne sais pas si tu auras le même comportement avec un autre SGBD...

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Donc,

    Avec un TADOConnection et cette méthode, cela devrais augmenter les performances de mes requêtes ...

    Pour ce qui est du pool de connexion, pourriez-vous me donner plus de détail?

    Je ferme toujours ma connexion lorsque le travail est fini ... (soit une ou plusieurs requêtes). Donc je crée ma connexion assez souvent.

    Y a t-il une façon quelconque de créer son propre pool?

    Merci de m'accorder de votre temps précieux, cela est très apprécié.

Discussions similaires

  1. Réponses: 9
    Dernier message: 22/12/2008, 11h36
  2. Delphi 6 - ADO introuvable
    Par repié dans le forum Bases de données
    Réponses: 4
    Dernier message: 28/09/2006, 15h41
  3. [Delphi 6] [ADO]
    Par KrusK dans le forum Bases de données
    Réponses: 9
    Dernier message: 12/07/2005, 14h10
  4. Delphi et ADO
    Par mmm dans le forum Bases de données
    Réponses: 2
    Dernier message: 24/08/2004, 16h46
  5. [DELPHI 5] [ADO] [ORACLE 8i] Getfieldnames + Blob....
    Par tpetitpi dans le forum Bases de données
    Réponses: 4
    Dernier message: 26/03/2004, 15h35

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