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:
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
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); }
J'ai donc directement employé un appel à la procédure avant le throw SQLException qui allait arrêter l'application.
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")); }
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
en fait au début de ce code j'ai une liste de syntagmes dans la variable pointée par pListOfChunk
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
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)
J'ai besoin d'abord de comprendre ce commentaire et principalement la syntaxe utilisée Je ne sais pas bien comprendre les T1, T2,...
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) // ; //************************************************************************************
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
Je suis intéressé par vos réponses
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 //![]()
Partager