关于数据库:分布式数据库SQL优化之Plan-Hint

4次阅读

共计 1496 个字符,预计需要花费 4 分钟才能阅读完成。

Part 1 – 对于 Hint

Hint 是嵌入 SQL 语句的对优化器进行提醒的信息,是 DBA 进行 SQL 优化的罕用伎俩。SQL 语句通过优化器 (规定优化(RBO)、代价优化(CBO)),通常会抉择正确的查问门路,然而智者千虑,必有一失,有时优化器也会抉择一个很差的打算,使得该条 SQL 查问变得很慢,此时须要 DBA 人为干涉(通过给 SQL 语句减少一个正文),通知优化器要抉择指定的拜访门路(full scan、index scan) 或 join 类型(merge、hash、lookup),使得该条 SQL 语句能够高效的运行。

Part 2 – Hint 的应用

通过 /+ … / 的正文模式放在 SELECT 关键字之后,多个 hint 之间用逗号隔开。

例如 select /+use_index(t, index1)/ * from t where a = 10 and b = 20;

如下图所示,通过 RBO 会失去如下 normalized plan,而 /+ use_index(t, index1)/ 将作用于 scan 抉择的过程,这将通知优化器在抉择表 t 的拜访门路 (① ② ③) 时,抉择②索引 index1。

Part 3 – Hint 在云溪数据库中的

解析和利用流程

整体流程如下图 3.1 所示:

图 3.1 hint 解析应用流程

第一步:输出带有 hint SQL 语句,如下所示

第二步:parser 编译解析;

第三步:将 AST 中的 hint 信息保留在 HintSet 中;

第四步:Builder 从 AST 中获取 hint 信息,将对应 hint 解析到 TableHint 和 IndexHint 构造体中;

第五步:normalized plan 阶段(RBO),通过调用 buildScan 为表构建 ScanFlags,调用 buildJoin 为表构建 JoinFlags;

第六步:在 CBO 阶段进行摸索时,依据组成员的 Flags 信息,通过开销大小,来阻止某些等价表达式的生成,并生成 hint 须要的表达式,从而减小搜寻空间;

第七步:生成 hint 作用之下的最优查问打算。

Part 4 – Hint 在云溪数据库中

不同阶段的表现形式

SQL 语句中:显示指定要在表 c 上强制应用 idx2,与 c 和 o 相干的 join 操作不容许应用 NLJ 算子;

通过 parser 后,hint 信息保留在 HintSet 中;

在 Builder 中,hint 信息以对象 index 和 table 为单位进行保留;

在规范化打算树和 Memo 构造体中,hint 信息存在对应的 Expr 构造体中。

具体流程如下图 4.1 所示:

图 4.1 hint 在不同阶段的表现形式图

Part 5 – Hint 对优化器的影响

图 5.1 构造解释:

图 5.1 hint 作用图

bestHT 存储着每个 Group 的代价最低的表达式。

exprHT 存储所有摸索进去的表达式。

Group 为逻辑等价的关系表达式的汇合。

在云溪数据库中 hint 影响打算的伎俩次要有两个,一个是摸索阶段中,缩小表达式的生成(例如指定 megejoin,失常状况下会生成 merge、lookup、hash 三种连贯类型,然而指定了 mergejoin,就会间接不生成其余的的表达式),如下①;另一个是代价计算阶段中返回一个很大的代价 hugeCost(例如针对 t1,指定 index1,而后对于其余的拜访办法,则会间接返回很大的代价),如下③。

Hint 对优化器的影响如下:

① 排除了若干操作,缩小了 Memo 构造体中表达式的个数,如下图 X 号所示;

② 决定相干 Group 的最优打算抉择,如下图 Group 1;

③ Group 1 中,#1 作为规范化表达式必然存在于组中,然而,它的代价被设置为 hugeCost;

③ 因为应用 ForceIndex,在摸索阶段应用其它索引的表达式不会被优化器抉择;

⑤ 最终影响最优打算树的抉择。

正文完
 0