forked from postgrespro/aqo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaqo.c
160 lines (138 loc) · 4.92 KB
/
aqo.c
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* aqo.c
* Adaptive query optimization extension
*
* Copyright (c) 2016-2020, Postgres Professional
*
* IDENTIFICATION
* aqo/aqo.c
*/
#include "aqo.h"
PG_MODULE_MAGIC;
void _PG_init(void);
/* Strategy of determining feature space for new queries. */
int aqo_mode;
bool force_collect_stat;
/* GUC variables */
static const struct config_enum_entry format_options[] = {
{"intelligent", AQO_MODE_INTELLIGENT, false},
{"forced", AQO_MODE_FORCED, false},
{"controlled", AQO_MODE_CONTROLLED, false},
{"learn", AQO_MODE_LEARN, false},
{"frozen", AQO_MODE_FROZEN, false},
{"disabled", AQO_MODE_DISABLED, false},
{NULL, 0, false}
};
/* Parameters of autotuning */
int aqo_stat_size = 20;
int auto_tuning_window_size = 5;
double auto_tuning_exploration = 0.1;
int auto_tuning_max_iterations = 50;
int auto_tuning_infinite_loop = 8;
/* stat_size > infinite_loop + window_size + 3 is required for auto_tuning*/
/* Machine learning parameters */
/*
* Defines where we do not perform learning procedure
*/
const double object_selection_prediction_threshold = 0.3;
/*
* This parameter tell us that the new learning sample object has very small
* distance from one whose features stored in matrix already.
* In this case we will not to add new line in matrix, but will modify this
* nearest neighbor features and cardinality with linear smoothing by
* learning_rate coefficient.
*/
const double object_selection_threshold = 0.1;
const double learning_rate = 1e-1;
/* The number of nearest neighbors which will be chosen for ML-operations */
int aqo_k = 3;
double log_selectivity_lower_bound = -30;
/*
* Currently we use it only to store query_text string which is initialized
* after a query parsing and is used during the query planning.
*/
MemoryContext AQOMemoryContext;
QueryContextData query_context;
/* Additional plan info */
int njoins;
char *query_text = NULL;
/* Saved hook values */
post_parse_analyze_hook_type prev_post_parse_analyze_hook;
planner_hook_type prev_planner_hook;
ExecutorStart_hook_type prev_ExecutorStart_hook;
ExecutorEnd_hook_type prev_ExecutorEnd_hook;
set_baserel_rows_estimate_hook_type prev_set_baserel_rows_estimate_hook;
get_parameterized_baserel_size_hook_type prev_get_parameterized_baserel_size_hook;
set_joinrel_size_estimates_hook_type prev_set_joinrel_size_estimates_hook;
get_parameterized_joinrel_size_hook_type prev_get_parameterized_joinrel_size_hook;
copy_generic_path_info_hook_type prev_copy_generic_path_info_hook;
ExplainOnePlan_hook_type prev_ExplainOnePlan_hook;
/*****************************************************************************
*
* CREATE/DROP EXTENSION FUNCTIONS
*
*****************************************************************************/
void
_PG_init(void)
{
DefineCustomEnumVariable("aqo.mode",
"Mode of aqo usage.",
NULL,
&aqo_mode,
AQO_MODE_CONTROLLED,
format_options,
PGC_USERSET,
0,
NULL,
NULL,
NULL);
DefineCustomBoolVariable(
"aqo.force_collect_stat",
"Collect statistics at all AQO modes",
NULL,
&force_collect_stat,
false,
PGC_USERSET,
0,
NULL,
NULL,
NULL
);
prev_planner_hook = planner_hook;
planner_hook = aqo_planner;
prev_post_parse_analyze_hook = post_parse_analyze_hook;
post_parse_analyze_hook = get_query_text;
prev_ExecutorStart_hook = ExecutorStart_hook;
ExecutorStart_hook = aqo_ExecutorStart;
prev_ExecutorEnd_hook = ExecutorEnd_hook;
ExecutorEnd_hook = aqo_ExecutorEnd;
prev_set_baserel_rows_estimate_hook = set_baserel_rows_estimate_hook;
set_baserel_rows_estimate_hook = aqo_set_baserel_rows_estimate;
prev_get_parameterized_baserel_size_hook = get_parameterized_baserel_size_hook;
get_parameterized_baserel_size_hook = aqo_get_parameterized_baserel_size;
prev_set_joinrel_size_estimates_hook = set_joinrel_size_estimates_hook;
set_joinrel_size_estimates_hook = aqo_set_joinrel_size_estimates;
prev_get_parameterized_joinrel_size_hook = get_parameterized_joinrel_size_hook;
get_parameterized_joinrel_size_hook = aqo_get_parameterized_joinrel_size;
prev_copy_generic_path_info_hook = copy_generic_path_info_hook;
copy_generic_path_info_hook = aqo_copy_generic_path_info;
prev_ExplainOnePlan_hook = ExplainOnePlan_hook;
ExplainOnePlan_hook = print_into_explain;
parampathinfo_postinit_hook = ppi_hook;
init_deactivated_queries_storage();
AQOMemoryContext = AllocSetContextCreate(TopMemoryContext,
"AQOMemoryContext",
ALLOCSET_DEFAULT_SIZES);
}
PG_FUNCTION_INFO_V1(invalidate_deactivated_queries_cache);
/*
* Clears the cache of deactivated queries if the user changed aqo_queries
* manually.
*/
Datum
invalidate_deactivated_queries_cache(PG_FUNCTION_ARGS)
{
fini_deactivated_queries_storage();
init_deactivated_queries_storage();
PG_RETURN_POINTER(NULL);
}