@@ -4570,8 +4570,10 @@ typedef struct
4570
4570
int n_params ;/* number of parameters extracted for this query */
4571
4571
int16 format ;/* portal output format */
4572
4572
bool disable_autoprepare ;/* disable preparing of this query */
4573
- uint64 non_prepared_time ;/* averge time of original (non-prepared) query execution (sum of autoprepare_threshold query execution times) */
4574
- uint64 prepared_time ;/* averge time of prepared query execution (sum of autoprepare_threshold query execution times) */
4573
+ uint64 non_prepared_time_sum ;/* sum of times of non-prepared query execution (up to autoprepare_threshold measurements) */
4574
+ uint64 prepared_time_sum ;/* sum of times of prepared query execution (up to autoprepare_threshold measurements) */
4575
+ double non_prepared_time_sum2 ;/* sum of squares of non-prepared query execution (up to autoprepare_threshold measurements) */
4576
+ double prepared_time_sum2 ;/* sum of squares of prepared query execution (up to autoprepare_threshold measurements) */
4575
4577
}plan_cache_entry ;
4576
4578
4577
4579
static uint32 plan_cache_hash_fn (const void * key ,Size keysize )
@@ -4652,11 +4654,13 @@ static void end_exec_simple(void)
4652
4654
{
4653
4655
long secs ;
4654
4656
int usecs ;
4657
+ uint64 elapsed ;
4655
4658
TimestampDifference (exec_start_timestamp ,
4656
4659
GetCurrentTimestamp (),
4657
4660
& secs ,& usecs );
4658
-
4659
- entry -> non_prepared_time += secs * USECS_PER_SEC + usecs ;
4661
+ elapsed = secs * USECS_PER_SEC + usecs ;
4662
+ entry -> non_prepared_time_sum += elapsed ;
4663
+ entry -> non_prepared_time_sum2 += elapsed * elapsed ;
4660
4664
}
4661
4665
}
4662
4666
@@ -5031,8 +5035,10 @@ static bool exec_cached_query(const char *query_string, List *parsetree_list)
5031
5035
autoprepare_cached_plans -= 1 ;
5032
5036
}
5033
5037
entry -> exec_count = 0 ;
5034
- entry -> prepared_time = 0 ;
5035
- entry -> non_prepared_time = 0 ;
5038
+ entry -> prepared_time_sum = 0 ;
5039
+ entry -> non_prepared_time_sum = 0 ;
5040
+ entry -> prepared_time_sum2 = 0 ;
5041
+ entry -> non_prepared_time_sum2 = 0 ;
5036
5042
entry -> plan = NULL ;
5037
5043
entry -> disable_autoprepare = false;
5038
5044
}
@@ -5358,24 +5364,32 @@ static bool exec_cached_query(const char *query_string, List *parsetree_list)
5358
5364
/* Calculate average time of execution of prepared query */
5359
5365
long secs ;
5360
5366
int usecs ;
5367
+ uint64 elapsed ;
5361
5368
TimestampDifference (exec_start_timestamp ,
5362
5369
GetCurrentTimestamp (),
5363
5370
& secs ,& usecs );
5364
-
5365
- entry -> prepared_time += secs * USECS_PER_SEC + usecs ;
5371
+ elapsed = secs * USECS_PER_SEC + usecs ;
5372
+ entry -> prepared_time_sum += elapsed ;
5373
+ entry -> prepared_time_sum2 += elapsed * elapsed ;
5366
5374
5367
5375
if (entry -> exec_count == autoprepare_threshold * 2 )
5368
5376
{
5369
5377
/* Now we can compare average times of prepared and non-prepared queries execution */
5370
- if (entry -> prepared_time > entry -> non_prepared_time )
5378
+ int n = autoprepare_threshold ;
5379
+ double prepared_time_deviation = sqrt ((entry -> prepared_time_sum2 - (double )entry -> prepared_time_sum * entry -> prepared_time_sum /n )/n );
5380
+ double non_prepared_time_deviation = sqrt ((entry -> non_prepared_time_sum2 - (double )entry -> non_prepared_time_sum * entry -> non_prepared_time_sum /n )/n );
5381
+ if (entry -> prepared_time_sum - prepared_time_deviation * n > entry -> non_prepared_time_sum + non_prepared_time_deviation * n )
5371
5382
{
5372
5383
/*
5373
5384
* Disable autoprepare if average time of execution of prepared query
5374
5385
* is worser than of non-prepared query
5375
5386
*/
5376
5387
entry -> disable_autoprepare = true;
5377
- elog (LOG ,"Disable autoprepared plan for %s because its average time %ld is greater than time of non-prepared query %ld" ,
5378
- query_string ,entry -> prepared_time ,entry -> non_prepared_time );
5388
+ elog (LOG ,"Disable autoprepared plan for %s (generic cost=%lg, avg custom cost=%lg, avg=%lg, dev=%lg) because its worser than non-prepared plan (avg=%lg, dev=%lg)" ,
5389
+ query_string ,
5390
+ psrc -> generic_cost ,psrc -> num_custom_plans != 0 ?psrc -> total_custom_cost /psrc -> num_custom_plans :0 ,
5391
+ (double )entry -> prepared_time_sum /n ,prepared_time_deviation ,
5392
+ (double )entry -> non_prepared_time_sum /n ,non_prepared_time_deviation );
5379
5393
}
5380
5394
}
5381
5395
}