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

Bases de données Delphi Discussion :

Kbmmemtable / DisableControls / DbGrid


Sujet :

Bases de données Delphi

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut Kbmmemtable / DisableControls / DbGrid
    Salut,

    J'ai un problème, j'ai un Kbmmemtable branché sur un Datasource branché sur un DBGrid....
    Une Base de données Firebird.

    lorsque je charge ma Table mémoire je fait comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Transaction.StartTransaction;
    UIBDataSet.SQL.Text := 'SELECT * FROM TOTO';
    UIBDataSet.Open;
    KBM.DisableControls;
    KBM.AfterScroll := NIL;
    KBM.LoadFromDataSet(DM_XPLAN.UIBDataSet, [mtcpoStructure]);
    UIBDataSet.Close;
    KBM.AfterScroll := KBMAfterScroll;
    KBM.EnableControls;
    Mon select me ramène 3000 Engs, le LoadFromDataSet met 3 secondes à charger.... très long !

    J'avais cru comprendre que le DisableControls permettait d’empêcher le refresh dans les composants branchés sur la Table Mémoire...

    Avec le Code qui suit, en mettant le Enabled False / True sur mon DBGRID au lieu d'utiliser DisabledControls / EnabledControls ...le LoadFromDataSet met 1/2 seconde pour charger la Requete .......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Transaction.StartTransaction;
    UIBDataSet.SQL.Text := 'SELECT * FROM TOTO';
    UIBDataSet.Open;
    DBGRID.Enabled := False;
    KBM.AfterScroll := NIL;
    KBM.LoadFromDataSet(DM_XPLAN.UIBDataSet, [mtcpoStructure]);
    UIBDataSet.Close;
    KBM.AfterScroll := KBMAfterScroll;
    DBGRID.Enabled := True;
    Si quelqu'un avait une explication ....

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Que renvoie le code suivant ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(BoolToStr(DBGRID.DataSource.DataSet = KBM), true);
    As-tu comparer les performances avec le TClientDataset ?
    Ou même le TMemoryDataSet de Franck SORIANO

    Sinon, plus ta DB grossira plus tu auras d'enregistrement, au lieu de récupérer toute la table, il serait plus performant de n'en récupérer une partie, cela réduit la consommation Mémoire, l'utilisation CPU sur le Serveur ainsi que sur le Client mais aussi réduit le flux sur le réseau !
    Sur une application massivement distribué dans une entreprise, c'est important de penser à cela !
    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
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    intrigué , j'ai fait un test différent (hors KBMTable) pour voir s'il y avait une différence de temps entre un DisableControls/EnableControls et un DBGrid.Enable:=False/True .

    Contexte :
    un datasource avec un grand nombre d'enregistrements (32000) , une DBGrid liée et 2 boutons un pour les Disable/Enable l'autre pour le Enable False/true

    pour chacun de ces boutons je ferme la table, la réouvre et vais en fin de Fichier (LAST) , un tickcount du temps de l'opération pour avoir une idée

    pas le top tout ça , mais c'est pour la bonne cause

    Go :
    c'est effectivement flagrant
    1295 pour le couple disableControls/EnableControls
    1270 pour le couple Enable False/True
    autant dire rien , l'erreur se situerait-elle dans KBMmemtable ? probable, cela fait longtemps que je ne l'ai plus utilisé (D2006 hélas désinstallé)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Que de donne ce 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
     
    Transaction.StartTransaction;
    UIBDataSet.SQL.Text := 'SELECT * FROM TOTO';
    UIBDataSet.Open;
     
    CDS := TClientDataSet.Create(UIBDataSet);
    DSP := DataSetProvider.Create(UIBDataSet);
    DBGRID.DataSource.DataSet := CDS;
    CDS.AfterScroll := NIL;
     
    CDS.SetProvider(UIBDataSet);
    CDS.PacketRecords := -1; // garanti la copié des données !
    CDS.Open; // Copie !
     
    CDS.AfterScroll := KBMAfterScroll;
    UIBDataSet.Close;



    Citation Envoyé par SergioMaster Voir le message
    vais en fin de Fichier (LAST)
    tu as fais directement Last ou un while Oef\Next ?

    On a suppose que le code de LoadFromDataSet étant un while Oef\Next ? qui lit UIBDataSet et rempli KBM

    KBM grossi au fur et à mesure, on peut espérer que les auteurs ont fait en interne dans LoadFromDataSet un DisableControls/EnableControls dans le cas contraire, je trouverais cela franchement douteux !

    Par exemple Assign, implique en interne quand c'est disponible BeginUpdate\EndUpdate, il y a quelques conventions à respecter !


    J'ai fais le test sur un TClientDataSet de 2300 lignes

    Open DisableControls/EnableControls : Total 640 à 710 ms (140 à 170 pour Open)
    Open Enabled False/True : Catastrophique ! : Total 70 000 ms !!!

    Enabled n'a AUCUN effet !

    Code c++ : 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
    //---------------------------------------------------------------------------
    void __fastcall TDBManipForm::BtnCDSBasicsLoadOpenClick(TObject *Sender)
    {
      DWORD OpenStart = GetTickCount();
     
      ClientDataSetBasics->Open(); // Lit le XML contenant les données indiquées par la propriété FileName
     
      int OpenDuration = GetTickCount() - OpenStart;
      OutputDebugStringW(IntToStr(OpenDuration).c_str());
     
      ClientDataSetBasics->DisableControls();
    //  DBGridCDSBasics->Enabled = false;
      while ( ! ClientDataSetBasics->Eof)
        ClientDataSetBasics->Next();
    //  DBGridCDSBasics->Enabled = true;
      ClientDataSetBasics->EnableControls();
     
      int NextDuration = GetTickCount() - OpenStart;
      OutputDebugStringW(IntToStr(NextDuration).c_str());
    }

    Au lieu d'une boucle de lecture, voici une boucle d'écriture

    Fill DisableControls/EnableControls : 140 ms pour 1000 lignes
    Fill Enabled False/True : Catastrophique ! : 288 000 ms


    Code c++ : 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
    void __fastcall TDBManipForm::BtnCDSBasicsFillRowClick(TObject *Sender)
    {
      DWORD FillStart = GetTickCount();
     
      ClientDataSetBasics->DisableControls();
    //  DBGridCDSBasics->Enabled = false;
      for (int i = 0; i < StrToIntDef(EdFillRowCount->Text, 1); i++)
      {
        ClientDataSetBasics->Append();
        ClientDataSetBasics->FieldByName("Champ1")->AsInteger = ClientDataSetBasics->RecordCount + 1;
        ClientDataSetBasics->FieldByName("Champ2")->AsString = "->" + IntToStr(ClientDataSetBasics->FieldByName("Champ1")->AsInteger);
        ClientDataSetBasics->FieldByName("Champ3")->AsBoolean = ClientDataSetBasics->FieldByName("Champ1")->AsInteger & 1;
        ClientDataSetBasics->FieldByName("Champ4")->AsDateTime = Now();
        ClientDataSetBasics->FieldByName("Champ5")->AsVariant = UTF8Decode("Привет");
        ClientDataSetBasics->Post();
      }
    //  DBGridCDSBasics->Enabled = true;
      ClientDataSetBasics->EnableControls();
     
      int FillDuration = GetTickCount() - FillStart;
      OutputDebugStringW(IntToStr(FillDuration).c_str());
    }

    Via TDataSetProvider, le XML contient 6300 lignes, 300 ms, c'est à peine plus long que le simple Open

    Code c++ : 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
    //---------------------------------------------------------------------------
    void __fastcall TDBManipForm::BtnCDSBasicsLoadOpenClick(TObject *Sender)
    {
      DWORD FillStart = GetTickCount();
     
      TClientDataSet * Tmp = new TClientDataSet(NULL);
      Tmp->FileName = ExtractFilePath(Application->ExeName) + ExtractFileName(ChangeFileExt(Application->ExeName, ".CDS.Basics.xml"));
      Tmp->Open();
      TDataSetProvider* TmpPrv = new TDataSetProvider(NULL);
      ClientDataSetBasics->SetProvider(Tmp);
      ClientDataSetBasics->PacketRecords = -1; // garanti la copié des données !
      TmpPrv->DataSet = Tmp;
     
      ClientDataSetBasics->Open();
      ClientDataSetBasics->SetProvider(NULL);
      TmpPrv->DataSet = NULL; // on détache, on ne conserve que la copie en mémoire
     
      delete Tmp;
      delete TmpPrv;
     
      int FillDuration = GetTickCount() - FillStart;
      OutputDebugStringW(IntToStr(FillDuration).c_str());
    }
    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

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Merci pour vos réponses ...

    ShaiLeTroll, pour ta première question Avant et Après le DisableControls : DBGRID.DataSource.DataSet est toujours = à KBM.

    Et ne t'inquiète pas pour les perf de ma BDD, c'est juste que, c'est un cas bien précis ou j'affiche une partie de ma BDD / rapport à un moteur de recherche.

    SergioMaster, ou mais je ne l'avait peut être pas précisé clairement mais c'est vraiment l'instruction KBM.LoadFromDataSet qui passe de 3sec. à 1/2 sec. alors oui peut être un bug des Kbmmemtable...

    ShaiLeTroll,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Transaction.StartTransaction;
    UIBDataSet.SQL.Text := 'SELECT * FROM TOTO';
    UIBDataSet.Open;
     
    CDS := TClientDataSet.Create(UIBDataSet);
    DSP := DataSetProvider.Create(UIBDataSet);
    DBGRID.DataSource.DataSet := CDS;
    CDS.AfterScroll := NIL;
     
    CDS.SetProvider(UIBDataSet);
    CDS.PacketRecords := -1; // garanti la copié des données !
    CDS.Open; // Copie !
     
    CDS.AfterScroll := KBMAfterScroll;
    me renvoie des EConvertError : 0,0 n'est pas une heure entière correct....

    je ne connais pas du tout ses composants ... mais je vais aller lire le document de Pascal Jankowski.

    J'ai checké les sources des KBM et en effet j'ai bien trouvé dans le LoadFromDataset :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SourceDisabled:=Source.ControlsDisabled;
     
    // Dont update controls while scrolling through source.
    if not SourceDisabled then Source.DisableControls;
    j'ai donc supprimé mon DisabledControls / EnabledControls de ma procédure de chargement, sans touché à Enabled True de mon DBGRID et je retombe à 1/2 sec.
    Du coup je refait un essais en remettant le DisabledControls / EnabledControls et je repasse à mes 3 sec..... Grrrrrr c'est vraiment bizarre ...

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    Citation Envoyé par silmortes Voir le message
    me renvoie des EConvertError : 0,0 n'est pas une heure entière correct....
    tout pourri le code que j'ai fourni, je l'ai mal recopié dans la version 100% CDS

    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
    Transaction.StartTransaction;
    UIBDataSet.SQL.Text := 'SELECT * FROM TOTO';
    UIBDataSet.Open;
     
    CDS := TClientDataSet.Create(UIBDataSet);
    DSP := DataSetProvider.Create(UIBDataSet);
    DBGRID.DataSource.DataSet := CDS;
    CDS.AfterScroll := NIL;
     
    CDS.SetProvider(DSP); // ça change !
    CDS.PacketRecords := -1;
    DSP.DataSet := UIBDataSet; // ça oublié !
     
    CDS.Open; 
     
    CDS.AfterScroll := KBMAfterScroll;


    Citation Envoyé par silmortes Voir le message
    ... et en effet j'ai bien trouvé dans le LoadFromDataset ControlsDisabled...
    C'est rassurant !

    Citation Envoyé par silmortes Voir le message
    Du coup je refait un essais en remettant le DisabledControls / EnabledControls et je repasse à mes 3 sec..... Grrrrrr c'est vraiment bizarre ...
    DisabledControls et EnabledControls fonctionne pourtant via un compteur, cela compte le nombre de +1 -1, une fois à zéro, cela ré-active l'affichage
    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

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    UIBDataSet.Open;
    CDS := TClientDataSet.Create(UIBDataSet);
    DSP := TDataSetProvider.Create(UIBDataSet);
    DBGRID1.DataSource.DataSet := CDS;
    CDS.AfterScroll := NIL;
    CDS.SetProvider(DSP);
    CDS.PacketRecords := -1; // garanti la copié des données !
    DSP.DataSet := UIBDataSet; 
    CDS.Open;
    CDS.AfterScroll := KBMAfterScroll;
    DM_XPLAN.UIBDataSet.Close;
    Mmmm toujours le même message lol

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 : 13 452
    Points : 24 863
    Points
    24 863
    Par défaut
    A la place du TClientDataSet, utilise un TIBClientDataSet, il gère peut-être mieux ce genre de chose !

    Je crois que TIBClientDataSet remplace même ton UIBDataSet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DBGRID.DataSource.DataSet := IBClientDataSet;
    IBClientDataSet.CommandText := 'SELECT * FROM TOTO';
    IBClientDataSet.Open();
    EDIT : je viens de voir à l'instant que c'est du UIBDataSet depuis le début, je pensais que tu utilisais un bon vieux IBDataSet
    Donc oublie le TIBClientDataSet, cela ne fonctionnera surement pas !

    Au final, tu as réussi à avoir un temps correct, possible qu'un bug dans le KBM ne supporte pas les Disable\Enabled imbriqué !
    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

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 46
    Points : 26
    Points
    26
    Par défaut
    Oui en effet au final, j'ai réussi a avoir un résultat digne de ce nom, cependant je penses qu'en effet il y a un problème avec imbrication du DisableControls.... cela reste quand même étrange car j'ai refait un projet propre avec les mêmes compos, le même code, et une requête qui me remonte 30000 Engs et impossible de reproduire le problème en question.... je referais un essais sur la même table car je ramenais beaucoup de VARCHAR assez long .... je vous tiens au jus et merci de votre aide .

Discussions similaires

  1. DBLookupComboBox dans DBGrid
    Par KThrax dans le forum Bases de données
    Réponses: 7
    Dernier message: 24/08/2004, 15h18
  2. A propos du composant DBGrid
    Par _Rico_ dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/07/2002, 09h18
  3. Couleur des lignes dans DBGrid
    Par eddie dans le forum C++Builder
    Réponses: 5
    Dernier message: 21/06/2002, 18h15
  4. associer une base de données(access) a un dbgrid
    Par ange1708 dans le forum MFC
    Réponses: 3
    Dernier message: 11/06/2002, 12h18
  5. [Kylix] Contrôle DBGrid
    Par KThrax dans le forum EDI
    Réponses: 1
    Dernier message: 10/05/2002, 14h18

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