Optmize query denormalization(2)

Avoid allocating an array of strings for extracting query argument
values, instead append the current parameter value directly in the
buffer used to store the denormalized query.

This avoids not only unnecessary memory allocations, but also copying
data between temporary memory and the buffer.
pull/481/head
Diego Fronza 2024-08-05 11:35:21 -03:00
parent 6acc63e5a6
commit a1f452c18c
1 changed files with 26 additions and 50 deletions

View File

@ -208,8 +208,11 @@ static void pgsm_add_to_list(pgsmEntry *entry, char *query_text, int query_len);
static pgsmEntry *pgsm_get_entry_for_query(uint64 queryid, PlanInfo *plan_info, const char *query_text, int query_len, bool create); static pgsmEntry *pgsm_get_entry_for_query(uint64 queryid, PlanInfo *plan_info, const char *query_text, int query_len, bool create);
static uint64 get_pgsm_query_id_hash(const char *norm_query, int len); static uint64 get_pgsm_query_id_hash(const char *norm_query, int len);
/* transform parameters value from datum to string*/ /*
static char **get_params_text_list(const ParamListInfo paramlist); * extract parameter value (Datum) from plist->params[idx], cast it to string then
* append the resulting string to the buffer.
*/
static void get_param_value(const ParamListInfo plist, int idx, StringInfoData *buffer);
/* denormalize the query, replace placeholders with actual values */ /* denormalize the query, replace placeholders with actual values */
static StringInfoData get_denormalized_query(const ParamListInfo paramlist, const char *query_text); static StringInfoData get_denormalized_query(const ParamListInfo paramlist, const char *query_text);
@ -707,7 +710,6 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
if (queryDesc->operation == CMD_SELECT && pgsm_enable_query_plan) if (queryDesc->operation == CMD_SELECT && pgsm_enable_query_plan)
{ {
int rv; int rv;
MemoryContext oldctx;
/* /*
* Making sure it is a per query context so that there's no memory * Making sure it is a per query context so that there's no memory
@ -4036,65 +4038,42 @@ get_query_id(JumbleState *jstate, Query *query)
} }
#endif #endif
static char ** void
get_params_text_list(const ParamListInfo paramlist) get_param_value(const ParamListInfo plist, int idx, StringInfoData *buffer)
{
StringInfoData buf;
int entry_num = paramlist->numParams;
int i;
char **params_text;
initStringInfo(&buf);
params_text = (char **)palloc0(sizeof(char *) * entry_num);
for(i = 0; i < entry_num; i++)
{
ParamExternData *param = &paramlist->params[i];
if (param->isnull || !OidIsValid(param->ptype))
{
appendStringInfoString(&buf, "NULL");
}
else
{ {
Oid typoutput; Oid typoutput;
bool typisvarlena; bool typisvarlena;
char *pstring; char *pstring;
ParamExternData *param;
Assert(idx < plist->numParams);
param = &plist->params[idx];
if (param->isnull || !OidIsValid(param->ptype))
{
appendStringInfoString(buffer, "NULL");
return;
}
getTypeOutputInfo(param->ptype, &typoutput, &typisvarlena); getTypeOutputInfo(param->ptype, &typoutput, &typisvarlena);
pstring = OidOutputFunctionCall(typoutput, param->value); pstring = OidOutputFunctionCall(typoutput, param->value);
appendStringInfo(&buf, "%s",pstring); appendStringInfo(buffer, "%s", pstring);
}
/* assign memory space and add terminate symbol at the end of string*/
params_text[i] = (char *)palloc0(sizeof(char) * (buf.len + 1));
memcpy(params_text[i], buf.data, buf.len);
memset(params_text[i] + sizeof(char) * buf.len,'\0',sizeof(char));
/*clean the temp buffer*/
resetStringInfo(&buf);
}
return params_text;
} }
StringInfoData StringInfoData
get_denormalized_query(const ParamListInfo paramlist, const char *query_text) get_denormalized_query(const ParamListInfo paramlist, const char *query_text)
{ {
int current_param; int current_param;
int param_num;
int i;
char **param_text;
const char *cursor_ori; const char *cursor_ori;
const char *cursor_curr; const char *cursor_curr;
StringInfoData result_buf; StringInfoData result_buf;
ptrdiff_t len; ptrdiff_t len;
param_text = get_params_text_list(paramlist);
param_num = paramlist->numParams;
current_param = 0; current_param = 0;
cursor_ori = query_text; cursor_ori = query_text;
cursor_curr = cursor_ori; cursor_curr = cursor_ori;
initStringInfo(&result_buf); initStringInfo(&result_buf);
do do
@ -4131,14 +4110,11 @@ get_denormalized_query(const ParamListInfo paramlist, const char *query_text)
cursor_curr = cursor_ori; cursor_curr = cursor_ori;
/* replace the placeholder with actual value */ /* replace the placeholder with actual value */
appendStringInfoString(&result_buf, param_text[current_param++]); get_param_value(paramlist, current_param, &result_buf);
++current_param;
} while (*cursor_ori != '\0'); } while (*cursor_ori != '\0');
/* free the query text array*/
for(i = 0; i < param_num; i++)
pfree(param_text[i]);
pfree(param_text);
return result_buf; return result_buf;
} }