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

InterBase Discussion :

Optimisation du code SQL


Sujet :

InterBase

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 022
    Par défaut Optimisation du code SQL
    Bonjour

    Lors de mes dernier messages, vous m'avez orienté sur IBPP. Cette orientation a été productive. j'ai d'ailleurs fait un apport sur ce site avec une procédure qui aide à avoir un avis pertinent sur les messages d'erreurs. Je renouvelle cette contribution à ce moment car elle me paraît extrêmement utile quand on développe avec SQL.

    Maintenant je suis sujet à des problèmes de performance, je met des syntagmes dans une base de donnée et avant d'optimiser mon code, je voudrais bien comprendre le code déjà optimisé dans mon application. c'est l'objet de ce message.
    Je vais donc rappeler la procédure de gestion des erreurs puis rapporter le problème d'optimisation.
    donc d'abord le code d'analyse des erreurs:
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    /*------------------------------------------------------------------------------------------------*/
    /*Name AnalyseSelectRequest                                                                       */
    /*Role          Analyse a select request                                                                                           */
    /*Interface                                                                                                       */
    /*In            Request                                                                           */
    /*              Result        indicate if the function has returned a result                      */
    /*In/Out        None                                                                              */
    /*Result        Error code                                                                        */
    /*Constraints                                                                                */
    /*Resources                                                                                       */
    /*PreCondition                                                                                    */
    /*------------------------------------------------------------------------------------------------*/
    //PROC AnalyseSelectRequest(In : Status
    //                          Result : Error code)
    static char          final_err_buff[2048];
    erc CInterbaseManager::AnalyseSqlStatus( ISC_STATUS * status_vector)
    {
       enum enDeleteDatabaseError
       {
          ERROR_DATABASE_ATTACHMENT = 1,
          ERROR_DATABASE_DELETION,
          ERROR_DATABASE_CONNECTED,
          ERROR_FILE_DOESNT_EXIST,
          ERROR_SERVER_NOT_CONNECTED,
       };
       erc              ErrorCode;
       char             err_buff[512];
       char             prev_err_buff[512];
       int              i;
       long*            pVector;
       char             msg[512];
     
       ErrorCode = INIT_NO_ERROR;
       if (status_vector[0] == 1 && status_vector[1])
       {
          final_err_buff[0] = 0;
          prev_err_buff[0] = 0;
          err_buff[0] = 0;
          pVector = status_vector;
          isc_interprete(  err_buff, &pVector);
          while( (strcmp( err_buff, prev_err_buff) != 0))
          {
             strcpy( prev_err_buff, err_buff);
             strcat( final_err_buff, err_buff);
             isc_interprete( err_buff, &pVector);
          }
          ErrorCode  |= objStrConv.CreateReturnCode(TYPE_ERROR,MSG_CANT_ATTACH_DATABASE,MODULE_ID_DBMS_MANAGER,
                                 DBMS_CINTERBASE_MANAGER, DELETE_DATABASE,
                                 ERROR_DATABASE_ATTACHMENT );
       }
       return( ErrorCode);
    }
    Je vais ensuite donner un exemple de mise en oeuvre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    if (status.Errors())
    	{
    		Close();
    		std::string context = "Statement::Prepare( ";
    		context.append(mSql).append(" )");
                    objCInterbaseManager.AnalyseSqlStatus( (ISC_STATUS*)status.Self());
    		throw SQLExceptionImpl(status, context.c_str(),
    			_("isc_dsql_prepare failed"));
    	}
    J'ai donc directement employé un appel à la procédure avant le throw SQLException qui allait arrêter l'application.

    Maintenant je vais parler d'optimisation des requêtes:
    D'abord je vais présenter le code non optimisé et je commenterai en langage naturel ce que je dois faire
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
              while( itChunk != pListOfChunk->end() && !bListProcessed)
              { //3
                 hidTemp = *itChunk;
                 wsRequestForm = L"";
                 wsRequestForm.append( SELECT);
                 wsRequestForm.append( CW_ID_WORD);
                 wsRequestForm.append( FROM);
                 wsRequestForm.append( CW_TABLE);
                 wsRequestForm.append( WHERE);
                 wsRequestForm.append( CW_ID_CHUNK);
                 wsRequestForm.append( EQ);
                 pTemp = _itow((int)*itChunk, pTemp, 10);
                 wsRequestForm.append( pTemp);
                 wssRequest.str(L"");
                 wssRequest << wsRequestForm;
                 dwNbResultFound = 0;
                 ErrorCode |= objCInterbaseManager.ExecuteSelectRequest(wssRequest.str(), &dwNbResultFound);
                 if( dwNbResultFound == 1)
                 { //4
                    bStillExist = true;
                    bEndReached = false;
                    hidFirstPreviousWord = 0;
                    ErrorCode |= objCInterbaseManager.First();
                    itChunk2 = pListOfChunk->begin();
                    while( itChunk2 != pListOfChunk->end() && !bEndReached)
                    { //5
                       hidTemp = *itChunk2;
                       itListWord = (*itListChunk)->ListWord.begin();
                       while( (itListWord != (*itListChunk)->ListWord.end()) && (bStillExist == true))
                       { //6
                          ullWordID = (*itListWord)->ullWordID;
                          if( ullWordID != hidFirstPreviousWord)
                          { //7
                              bFirstWord = true;
                              bStillExist = true;
                              hidChunkID = hidTemp;
                              ErrorCode |= objCInterbaseManager.GetHidDB( 1, hidWordId);
                              if( ullWordID != hidWordId)
                              { //8
                                 iSelectedPluriel++;
                                 bStillExist = false;
                              } //8
                              // Go to the next result of the request
                              if(bFirstWord == true)
                              { //8
                                 hidFirstPreviousWord = (*itListWord)->ullWordID;
                              } //8
                              bFirstWord = false;
                          } //7
                          itListWord++;
                       } //6
                       ErrorCode |= objCInterbaseManager.Next(bEndReached);
                       itChunk2++;
                    } //5
                    itChunk++;
                 } //4
                 bListProcessed = true;
              } //3
              pListOfChunk->clear();
           } //2
    en fait au début de ce code j'ai une liste de syntagmes dans la variable pointée par pListOfChunk
    et je veux vérifier qu'aucun de ces syntagmes (contenus dans pListOfChunk) n'est déjà présent dans la base; Je ressort avec un booleen bStillExist qui me dit false si le syntagme n'est pas dans la base et qu'il faut le créer.
    Je fais dans ce cadre de nombreux accés à la base pour avoir la liste des mots qui doivent être comparés aux mots du syntagme, jusqu'à trouver un mot différent.
    J'ai un modèle d'optimisation que je voudrais utiliser pour limiter les requète sql dans cette partie de code qui est parcouru majoritairement (c'est pour cela qu'il y a des compteurs (en variables statiques)
    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
     
    //************** exemple complet*****************************
    //      [SELECT
    //        T0.nuIdChunk
    //      FROM
    //        T_CHUNK T0, T_CHUNK_WORD T1 (premier mot)
    //        ,T_CHUNK_WORD T2 (N mot suivant), T_CHUNK_WORD T3 (N mot suivant)
    //      WHERE
    //        (T0.nuIdChunkType = ChunkType) AND (T0.siNbWord = size of ListWord) AND (T0.siIdLang = language) AND (T0.nuIdChunk= T1.nuIdChunk) (premier mot)
    //        AND (T1.nuIdChunk= T2.nuIdChunk) (N mot suivant)
    //        AND (T2.nuIdChunk= T3.nuIdChunk) (N mot suivant)
    //        AND(T1.nuIdWord = 1 AND T1.siWordRank = 1) (N mot)
    //        AND(T2.nuIdWord = 2 AND T2.siWordRank = 2) (N mot)
    //        AND(T3.nuIdWord = 3 AND T3.siWordRank = 3) (N mot)
    //        ;
    //************************************************************************************
    J'ai besoin d'abord de comprendre ce commentaire et principalement la syntaxe utilisée Je ne sais pas bien comprendre les T1, T2,...
    ni les Ti.nuidWord = i
    quelq'un saurait t'il me donner un pointeur vers l'explication conséquente ce serait
    J'ajouterai un morceau de code qui implémente le modèle en commentaire pris dans une autre partie de l'application
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
    //					[Increment the rank of the Word of the NGram "shWordNgramRank"]
                shWordNgramRank++;
    //					wssWhereItemRequest :=(("nuIdWord" = "ullWordID" of current item of "ListWord" of current item "ListNgram") AND
    //																("siWordRank"="shWordNgramRank"))
    //          exemple : (T1.nuIdWord = 2 AND T1.siWordRank = 1)
                wssWhereWordItemRequest.str(L"");
                wssWhereWordItemRequest << PB << L"T" << shWordNgramRank << DOT << NW_ID_WORD << EQ << (*itListWord)->ullWordID << AND <<
                                                 L"T" << shWordNgramRank << DOT << NW_WORD_RANK << EQ << shWordNgramRank << PE;
    //					IF (this the first word of "ListWord" of current item "ListNgram") THEN
                if (shWordNgramRank == 1)
                {
    //            exemple : T_NGRAM T0, T_NGRAM_WORD T1 (premier mot)
                  wssFromTableRequest  <<  NGRAM_TABLE << BLANK << L"T" << (shWordNgramRank-1) << CO << BLANK <<  NW_TABLE << BLANK << L"T" << shWordNgramRank;
    //            exemple : (T0.siDegree = 3) AND (T0.siIdLang = 1) AND (T0.nuIdNGram= T1.nuIdNGram) (premier mot)
                  wssWhereTableRequest << PB << NGRAM_DEGREE << EQ << (*itListNgram)->shDegree << PE
                                       << AND
                                       << PB << NGRAM_ID_LANG << EQ << Language << PE
                                       << AND
                                       << PB << DOT << NGRAM_ID_NGRAM << EQ << L"T" << shWordNgramRank << DOT<< NW_ID_NGRAM << PE;
                }
    //					ELSE
                else
                {
    //            exemple : , T_NGRAM_WORD T2 (N mot suivant)
                  wssFromTableRequest << CO << BLANK << NW_TABLE << BLANK << L"T" << shWordNgramRank;
    //            exemple : AND (T1.nuIdNGram = T2.nuIdNGram) (N mot suivant)
                  wssWhereTableRequest <<AND << PB << L"T" << (shWordNgramRank-1) << DOT << NW_ID_NGRAM << EQ
                                                   << L"T" <<  shWordNgramRank    << DOT << NW_ID_NGRAM << PE;
    //					FI
                }
    //          exemple : AND (T1.nuIdWord = 2 AND T1.siWordRank = 1) (N mot)
                wssWhereWordRequest << AND << wssWhereWordItemRequest.str();
    //					[Go to the next item of the list "ListWord" of current item "ListNgram"]
                itListWord++;
    //				OD
              }// while
    //			OD
    //
    Je suis intéressé par vos réponses

  2. #2
    Membre extrêmement actif
    Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2008
    Messages
    1 022
    Détails du profil
    Informations personnelles :
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 022
    Par défaut Il fallait mettre l'identifiant du mot dans la requète
    Voici le code optimisé qui marche
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
        iSize = ListChunk.size();
        pTemp = (wchar_t*)&wTemp;
        bEndReached = false;
        itListChunk = ListChunk.begin();
        while( (itListChunk != ListChunk.end()) && ErrorCode == INIT_NO_ERROR && iSize > 0)
        { //1
    //     [Verifiy that the chunk already exist] =
    //     DO
    //     IF (Number of words of current chunk > MAX_JOIN) THEN
    //        [Return the error code "ERR_MAX_JOIN_REACHED"]
    //     FI
           wssFromTableRequest.str(L"");
           wssWhereTableRequest.str(L"");
           wssWhereWordRequest.str(L"");
    //     shWordChunkRank:=0
           shWordChunkRank = 0;
           iSizeWord = (*itListChunk)->ListWord.size();
           if (iSizeWord > MAX_JOIN)
           { //2
              return( ERR_MAX_JOIN_REACHED);
           }
    //     [Shape the WHERE request]=
    //     DO
              shWordChunkRank = 0;
              wssFromTableRequest.str(L"");
              wssWhereTableRequest.str(L"");
              wssWhereWordRequest.str(L"");
    //	  WHILE (there is element in the list "ListWord" of current item "ListChunk") AND (there is no error)
              itListWord = (*itListChunk)->ListWord.begin();
              while( (itListWord != (*itListChunk)->ListWord.end()) && NO_ERROR_CODE )
              {
    //	    [Increment the rank of the word of the chunk "shWordChunkRank"]
                shWordChunkRank++;
    //	    wssWhereItemRequest :=(("nuIdWord" = "ullWordID" of current item of "ListWord" of current item "ListChunk") AND ("siWordRank"="shWordChunkRank"))
    //          exemple : (T1.nuIdWord = 1 AND T1.siWordRank = 1)
                wssWhereWordItemRequest.str(L"");
                wssWhereWordItemRequest << PB << L"T" << shWordChunkRank << DOT << CW_ID_WORD << EQ << (*itListWord)->ullWordID << AND <<
                                                 L"T" << shWordChunkRank << DOT << CW_WORD_RANK << EQ << shWordChunkRank << PE;
    //	    IF (this the first word of "ListWord" of current item "ListChunk") THEN
                if (shWordChunkRank == 1)
                {
    //            exemple : T_CHUNK T0, T_CHUNK_WORD T1 (premier mot)
                  wssFromTableRequest  <<  CHK_TABLE << BLANK << L"T" << (shWordChunkRank-1) << CO << BLANK <<  CW_TABLE << BLANK << L"T" << shWordChunkRank;
    //            exemple : (T0.nuIdChunkType = ChunkType) AND (T0.siNbWord = size of ListWord) AND (T0.siIdLang = language) AND (T0.nuIdChunk= T1.nuIdChunk) (premier mot)
                  wssWhereTableRequest << PB << L"T" << (shWordChunkRank-1) << DOT << CHK_ID_CHK_TYPE << EQ << (*itListChunk)->ChunkType << PE
                                       << AND
                                       << PB << L"T" << (shWordChunkRank-1) << DOT << CHK_NB_WORD << EQ << (*itListChunk)->ListWord.size() << PE
                                       << AND
                                       << PB << L"T" << (shWordChunkRank-1) << DOT << CHK_ID_LANG << EQ << Language << PE
                                       << AND
                                       << PB << L"T" << (shWordChunkRank-1) << DOT << CHK_ID_CHK << EQ << L"T" << shWordChunkRank << DOT<< CW_ID_CHUNK << PE;
                }
    //	    ELSE
                else
                {
    //            exemple : , T_CHUNK_WORD T2 (N mot suivant)
                  wssFromTableRequest << CO << BLANK << CW_TABLE << BLANK << L"T" << shWordChunkRank;
    //            exemple : AND (T1.nuIdChunk = T2.nuIdChunk) (N mot suivant)
                  wssWhereTableRequest <<AND << PB << L"T" << (shWordChunkRank-1) << DOT << CW_ID_CHUNK << EQ
                                                   << L"T" <<  shWordChunkRank    << DOT << CW_ID_CHUNK << PE;
    //					FI
                }
    //          exemple : AND (T1.nuIdWord = 1 AND T1.siWordRank = 1) (N mot)
                wssWhereWordRequest << AND << wssWhereWordItemRequest.str();
    //	    [Go to the next item of the list "ListWord" of current item "ListChunk"]
                itListWord++;
              }
    //
    //************** exemple complet ******************************************************
    //      [SELECT
    //        T0.nuIdChunk
    //      FROM
    //        T_CHUNK T0, T_CHUNK_WORD T1 (premier mot)
    //        ,T_CHUNK_WORD T2 (N mot suivant), T_CHUNK_WORD T3 (N mot suivant)
    //      WHERE
    //        (T0.nuIdChunkType = ChunkType) AND (T0.siNbWord = size of ListWord) AND (T0.siIdLang = language) AND (T0.nuIdChunk= T1.nuIdChunk) (premier mot)
    //        AND (T1.nuIdChunk= T2.nuIdChunk) (N mot suivant)
    //        AND (T2.nuIdChunk= T3.nuIdChunk) (N mot suivant)
    //        AND(T1.nuIdWord = 1 AND T1.siWordRank = 1) (N mot)
    //        AND(T2.nuIdWord = 2 AND T2.siWordRank = 2) (N mot)
    //        AND(T3.nuIdWord = 3 AND T3.siWordRank = 3) (N mot)
    //        ;
    //************************************************************************************
     
           wssRequest.str(L"");
           wssRequest <<   SELECT <<
                              L"T0" << DOT << CHK_ID_CHK <<
                            FROM <<
                              wssFromTableRequest.str() <<
                            WHERE <<
                              wssWhereTableRequest.str() <<
                              wssWhereWordRequest.str();
           dwNbResultFound = 0;
           bEndReached = false;
           ErrorCode |= m_pDBMSManager->ExecuteSelectRequest(wssRequest.str(), &dwNbResultFound);
    Merci à tous

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

Discussions similaires

  1. [MySQL] Optimisation de code SQL et php
    Par pablofr dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 13/02/2013, 23h09
  2. Optimisation d'un code SQL
    Par Myriam25 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/11/2007, 11h14
  3. [SQL - procStock ] optimisation du code (éviter les boucles)
    Par luimême dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 06/10/2005, 17h22
  4. [ SQL - proc stockée ] optimisation du code parcours curseur
    Par luimême dans le forum Langage SQL
    Réponses: 1
    Dernier message: 06/10/2005, 16h20
  5. Optimisation du code des ordres SQL
    Par Titouf dans le forum Langage SQL
    Réponses: 1
    Dernier message: 14/08/2005, 22h08

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