@@ -29,6 +29,7 @@ static bool auto_explain_log_triggers = false;
2929static bool auto_explain_log_timing = true;
3030static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT ;
3131static bool auto_explain_log_nested_statements = false;
32+ static double auto_explain_sample_ratio = 1 ;
3233
3334static const struct config_enum_entry format_options [] = {
3435 {"text" , EXPLAIN_FORMAT_TEXT , false},
@@ -47,6 +48,9 @@ static ExecutorRun_hook_type prev_ExecutorRun = NULL;
4748static ExecutorFinish_hook_type prev_ExecutorFinish = NULL ;
4849static ExecutorEnd_hook_type prev_ExecutorEnd = NULL ;
4950
51+ /* Is the current query sampled, per backend */
52+ static bool current_query_sampled = true;
53+
5054#define auto_explain_enabled () \
5155 (auto_explain_log_min_duration >= 0 && \
5256 (nesting_level == 0 || auto_explain_log_nested_statements))
@@ -159,6 +163,19 @@ _PG_init(void)
159163 NULL ,
160164 NULL );
161165
166+ DefineCustomRealVariable ("auto_explain.sample_ratio" ,
167+ "Fraction of queries to process." ,
168+ NULL ,
169+ & auto_explain_sample_ratio ,
170+ 1.0 ,
171+ 0.0 ,
172+ 1.0 ,
173+ PGC_SUSET ,
174+ 0 ,
175+ NULL ,
176+ NULL ,
177+ NULL );
178+
162179 EmitWarningsOnPlaceholders ("auto_explain" );
163180
164181 /* Install hooks. */
@@ -191,7 +208,15 @@ _PG_fini(void)
191208static void
192209explain_ExecutorStart (QueryDesc * queryDesc , int eflags )
193210{
194- if (auto_explain_enabled ())
211+ /*
212+ * For ratio sampling, randomly choose top-level statement. Either
213+ * all nested statements will be explained or none will.
214+ */
215+ if (auto_explain_log_min_duration >= 0 && nesting_level == 0 )
216+ current_query_sampled = (random () < auto_explain_sample_ratio *
217+ MAX_RANDOM_VALUE );
218+
219+ if (auto_explain_enabled () && current_query_sampled )
195220 {
196221 /* Enable per-node instrumentation iff log_analyze is required. */
197222 if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY ) == 0 )
@@ -210,7 +235,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags)
210235 else
211236 standard_ExecutorStart (queryDesc , eflags );
212237
213- if (auto_explain_enabled ())
238+ if (auto_explain_enabled () && current_query_sampled )
214239 {
215240 /*
216241 * Set up to track total elapsed time in ExecutorRun. Make sure the
@@ -280,7 +305,7 @@ explain_ExecutorFinish(QueryDesc *queryDesc)
280305static void
281306explain_ExecutorEnd (QueryDesc * queryDesc )
282307{
283- if (queryDesc -> totaltime && auto_explain_enabled ())
308+ if (queryDesc -> totaltime && auto_explain_enabled () && current_query_sampled )
284309 {
285310 double msec ;
286311
0 commit comments