From: Teodor Sigaev Date: Fri, 7 Apr 2017 14:10:56 +0000 (+0300) Subject: try to optimize reread stat X-Git-Url: http://sigaev.ru/git/gitweb.cgi?a=commitdiff_plain;h=58675e5fe74be3509bd3c882c4326b9f639bd249;p=online_analyze.git try to optimize reread stat --- diff --git a/online_analyze.c b/online_analyze.c index 50d8aca..c94497c 100644 --- a/online_analyze.c +++ b/online_analyze.c @@ -73,6 +73,16 @@ static ExecutorEnd_hook_type oldExecutorEndHook = NULL; static ProcessUtility_hook_type oldProcessUtilityHook = NULL; #endif +typedef enum CmdKind +{ + CK_SELECT = CMD_SELECT, + CK_UPDATE = CMD_UPDATE, + CK_INSERT = CMD_INSERT, + CK_DELETE = CMD_DELETE, + CK_TRUNCATE, + CK_CREATE +} CmdKind; + typedef enum { OATT_ALL = 0x03, @@ -342,7 +352,7 @@ makeRangeVarFromOid(Oid relOid) #endif static void -makeAnalyze(Oid relOid, CmdType operation, int32 naffected) +makeAnalyze(Oid relOid, CmdKind operation, int32 naffected) { TimestampTz now = GetCurrentTimestamp(); Relation rel; @@ -422,15 +432,20 @@ makeAnalyze(Oid relOid, CmdType operation, int32 naffected) else rstat = &dummyrstat; /* found == false for following if */ - if (found == false || rstat->rereadStat == true || naffected == 0) + if (!found) { + MemSet(rstat, 0, sizeof(*rstat)); + rstat->tableid = relOid; + newTable = true; + } - if (!found) - { - MemSet(rstat, 0, sizeof(*rstat)); - rstat->tableid = relOid; - } - Assert(rstat->tableid == relOid); + Assert(rstat->tableid == relOid); + + if (operation != CK_TRUNCATE && + (found == false || rstat->rereadStat == true)) + { + + rstat->rereadStat = false; tabentry = pgstat_fetch_stat_tabentry(relOid); @@ -447,16 +462,15 @@ makeAnalyze(Oid relOid, CmdType operation, int32 naffected) rstat->autovac_analyze_timestamp = tabentry->autovac_analyze_timestamp; rstat->analyze_timestamp = tabentry->analyze_timestamp; - rstat->rereadStat = false; - } - else - { - newTable = true; - rstat->rereadStat = true; } } - if (newTable || ( + if (naffected == 0) + rstat->rereadStat = true; + + if (newTable || + /* force analyze from after truncate */ + operation == CK_TRUNCATE || ( /* do not analyze too often, if both stamps are exceeded the go */ TimestampDifferenceExceeds(rstat->analyze_timestamp, now, online_analyze_min_interval) && TimestampDifferenceExceeds(rstat->autovac_analyze_timestamp, now, online_analyze_min_interval) && @@ -533,7 +547,25 @@ makeAnalyze(Oid relOid, CmdType operation, int32 naffected) rstat->autovac_analyze_timestamp = now; rstat->changes_since_analyze = 0; - rstat->rereadStat = true; + + switch(operation) + { + case CK_INSERT: + rstat->n_tuples += naffected; + break; + case CK_UPDATE: + rstat->n_tuples += naffected; + rstat->rereadStat = true; + break; + case CK_DELETE: + rstat->rereadStat = true; + break; + case CK_TRUNCATE: + rstat->n_tuples = 0; + break; + default: + break; + } /* update last analyze timestamp in local memory of backend */ if (tabentry) @@ -553,7 +585,25 @@ makeAnalyze(Oid relOid, CmdType operation, int32 naffected) if (tabentry) tabentry->changes_since_analyze += naffected; #endif - rstat->changes_since_analyze += naffected; + switch(operation) + { + case CK_INSERT: + rstat->changes_since_analyze += naffected; + rstat->n_tuples += naffected; + break; + case CK_UPDATE: + rstat->changes_since_analyze += 2 * naffected; + rstat->n_tuples += naffected; + case CK_DELETE: + rstat->changes_since_analyze += naffected; + break; + case CK_TRUNCATE: + rstat->changes_since_analyze = rstat->n_tuples; + rstat->n_tuples = 0; + break; + default: + break; + } } /* Reset local cache if we are over limit */ @@ -600,7 +650,7 @@ onlineAnalyzeHooker(QueryDesc *queryDesc) RangeTblEntry *rte = list_nth(queryDesc->plannedstmt->rtable, n-1); if (rte->rtekind == RTE_RELATION) - makeAnalyze(rte->relid, queryDesc->operation, naffected); + makeAnalyze(rte->relid, (CmdKind)queryDesc->operation, naffected); } } } @@ -629,7 +679,8 @@ onlineAnalyzeHookerUtility( ParamListInfo params, bool isTopLevel, #endif DestReceiver *dest, char *completionTag) { - RangeVar *tblname = NULL; + List *tblnames = NIL; + CmdKind op = CK_INSERT; #if PG_VERSION_NUM >= 100000 Node *parsetree = NULL; @@ -637,10 +688,21 @@ onlineAnalyzeHookerUtility( parsetree = pstmt->utilityStmt; #endif - if (parsetree && IsA(parsetree, CreateTableAsStmt) && - ((CreateTableAsStmt*)parsetree)->into && - online_analyze_enable) - tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel); + if (parsetree && online_analyze_enable) + { + if (IsA(parsetree, CreateTableAsStmt) && + ((CreateTableAsStmt*)parsetree)->into) + { + tblnames = + list_make1((RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel)); + op = CK_CREATE; + } + else if (IsA(parsetree, TruncateStmt)) + { + tblnames = list_copy(((TruncateStmt*)parsetree)->relations); + op = CK_TRUNCATE; + } + } #if PG_VERSION_NUM >= 100000 #define parsetree pstmt @@ -673,10 +735,16 @@ onlineAnalyzeHookerUtility( #undef parsetree #endif - if (tblname) { - Oid tblOid = RangeVarGetRelid(tblname, NoLock, true); + if (tblnames) { + ListCell *l; - makeAnalyze(tblOid, CMD_INSERT, -1); + foreach(l, tblnames) + { + RangeVar *tblname = (RangeVar*)lfirst(l); + Oid tblOid = RangeVarGetRelid(tblname, NoLock, true); + + makeAnalyze(tblOid, op, -1); + } } } #endif