openGauss源码解析(169)

openGauss源码解析:AI技术(16)

8.3.4 关键源码解析

慢SQL发现工具在项目中的源代码路径为:openGauss-server/src/gausskernel/dbmind/tools/sqldiag。

1. 项目结构

慢SQL发现工具文件结构如表8-6所示。

表8-6 慢SQL发现工具结构

文件结构

说明

preprocessing.py

SQL预处理方法

requirements.txt

依赖第三方库列表,通过pip –r安装

main.py

入口文件

test

测试文件集合

algorithm

项目核心代码

algorithm/sql_similarity

相似度计算方法

2. 总体流程解析

算法的总体流程在main.py中给出,根据传来的参数实例化算法模型后,进行训练、增量训练、预测等。main函数的核心代码如下所示。

def main(args):

logging.basicConfig(level=logging.INFO)

# 实例化算法模型,模板化模型或DNN模型

model = SQLDiag(args.model, args.csv_file, get_config(args.config_file))

# 训练模型

if args.mode == 'train':

# fit训练数据,提取模板或特征

model.fit()

# 模型保存

model.save(args.model_path)

# 预测

elif args.mode == 'predict':

# 加载模型

model.load(args.model_path)

# 标准化预测数据,获取结果

pred_result = model.transform()

# 保存输出结果

ResultSave().save(pred_result, args.predicted_file)

logging.info('predict result in saved in {}'.format(args.predicted_file))

# 更新模型

elif args.mode == 'finetune':

model.fine_tune(args.model_path)

model.save(args.model_path)

3. 模板化算法源码解析

通过模板化方法,实现在不获取SQL语句执行计划的前提下,依据语句逻辑相似度与历史执行记录,预测SQL语句的执行时间。主要源码如下:

class TemplateModel(AbstractModel):

# 初始化算法参数

def __init__(self, params):

super().__init__(params)

self.bias = 1e-5

self.__hash_table = dict(INSERT=dict(), UPDATE=dict(), DELETE=dict(), SELECT=dict(),

OTHER=dict())

self.time_list_size = params.time_list_size

self.knn_number = params.knn_number

self.similarity_algorithm = calc_sql_distance(params.similarity_algorithm)

def fit(self, data):

# 对每条sql语句按照粗、细粒度进行标准化,生成模板

for sql, duration_time in data:

if not self.check_illegal_sql(sql):

continue

fine_template, rough_template = get_sql_template(sql)

sql_prefix = fine_template.split()[0]

if sql_prefix not in self.__hash_table:

sql_prefix = 'OTHER'

# 更新粗粒度模板框架

if rough_template not in self.__hash_table[sql_prefix]:

self.__hash_table[sql_prefix][rough_template] = dict()

self.__hash_table[sql_prefix][rough_template]['info'] = dict()

# 更新细粒度模板框架

if fine_template not in self.__hash_table[sql_prefix][rough_template]['info']:

self.__hash_table[sql_prefix][rough_template]['info'][fine_template] = \

dict(time_list=[], count=0, mean_time=0.0, iter_time=0.0)

# 更新每个细粒度模板的执行时间、迭代时间、sql语句的计数。

self.__hash_table[sql_prefix][rough_template]['info'][fine_template]['count'] += 1

# 基于细粒度模板更新粗粒度模板信息

for sql_prefix, sql_prefix_info in self.__hash_table.items():

def transform(self, data):

predict_time_list = {}

for sql in data:

# sql语句不属于'INSERT', 'SELECT', 'UPDATE', 'DELETE', 'CREATE', 'DROP'任何一个,预测时间默认为-1

if not self.check_illegal_sql(sql):

predict_time_list[sql] = -1

continue

# 若预测的sql所对应的粗粒度模板不存在,执行模板相似度计算方法获取与所有粗粒度模板的相似度

if rough_template not in self.__hash_table[sql_prefix]:

for local_rough_template, local_rough_template_info in self.__hash_table[

sql_prefix].items():

similarity_info.append(

(self.similarity_algorithm(rough_template, local_rough_template), local_rough_template_info['mean_time']))

# 若预测的sql所对应的细粒度模板不存在,执行模板相似度计算方法获取与所有细粒度模板的相似度

else:

for local_fine_template, local_fine_template_info in \

self.__hash_table[sql_prefix][rough_template][

'info'].items():

similarity_info.append(

(self.similarity_algorithm(fine_template, local_fine_template),

local_fine_template_info['iter_time']))

# 基于KNN思想计算sql执行时间

topn_similarity_info = heapq.nlargest(self.knn_number, similarity_info)

return predict_time_list

posted @ 2024-05-06 10:24  openGauss-bot  阅读(1)  评论(0编辑  收藏  举报