概述:
在真实的客户场景中,其实我们不缺索引,索引推荐模块主要目的是去除冗余索引,使客户用更少索引达到相同甚至更好的查询效率。
该模块提供了三种索引推荐方法:
1:简单索引推荐:简单的保留高索引索引,推荐效果不理想
2:基于贪心算法的索引推荐:容易陷入局部最优
2:基于MTCS的索引推荐:AlphaGo也是基于该算法,推荐效果较好。
之前我司和一个高校合作设计了一个基于DQN的索引推荐算法,MTCS相较于DQN,计算速度更快,不需要事先训练好模型,效果也不弱与DQN。(DBMIND的Xtuner数据库智能调参模块也是基于MCTS)客户对推荐效果比较满意,但是不愿意安装PG的虚拟索引插件,导致改研究不了了之。目前我正在研究把虚拟索引和PG的内核(parser,rewriter,planner)抽取出来集成到索引推荐模块中,后续可以继续做分享。
下面主要是对基于负载的索引推荐进行解析,改方法是基于单条sql的索引推荐,单条的索引推荐主要是基于sql文本的利用专家规则来进行推荐的,我们此次不涉及该内容。该模块内容较大,我将会分成两篇来讲,这一篇主要讲解预处理和简单索引推荐部分,下一篇讲解复杂索引推荐。
模块:
components/dao/execute_factory.py:封装了一些静态方法。
components/dao/driver_execute.py:通过官方driver psycopg2连接数据库进行操作,debug时建议时候该方法,可读性较强。
components/dao/gsql_execute.py:通过python内置的模块subprocess和CMD命令行连接数据库进行操作。
components/index_advisor_workload.py:基于负载的索引推荐的核心部分,后面主要对该脚本解析。
components/MCTS.py:蒙特卡洛搜索树算法的实现。
简单索引推荐源码解析
index_advisor_workload.py/main(argv):
输入参数:
连接数据库
index_advisor_workload.py/index_advisor_workload():
1:sql压缩
①sql规范化后,相同的sql合并:
②将相似sql压缩为sql模版:
③将量纲变小,出现数除以限定的采样数
2:简单索引推荐
① 生成候选索引:
①-①:调用单条sql的索引推荐(拼接sql,使用数据库内置函数gs_index_advise)
①-②:对上一步推荐出来的索引进行过滤(虚拟索引 + explain)
①-②-①:过滤相同的索引列和索引类型
①-②-②:过滤无用索引
①-③:不同表的相同索引只保留一个
①-④:使用最左匹配原则过滤索引
②:可能会遇到某个sql执行较长时间,导致与数据库的连接断开。
③:计算不加索引的cost
④:遍历每个索引,计算使用该索引后的增益
⑤:保留高收益的索引