- OB 的计划缓存匹配规则是什么?是不是 SQL 文本完全一致才会命中缓存?
- 已经缓存了旧计划之后,新增 hint 的同文本 SQL 会不会继续复用旧计划?
- 如果想让 hint 马上生效,除了重启租户,有什么清理单条 SQL 计划缓存的办法?
关于 OceanBase V4 执行计划缓存和 Hint 的问题
根据您的提问,我会逐一解答您的问题。
1. SQL 加了 Hint 为什么不生效?
-
Hint 不生效的原因:如果在 SQL 中添加了 Hint,但是执行计划并没有按照预期的那样改变,可能有以下几个原因:
- Hint 使用规则:从文档片段 1 可知,如果指定表行为但在本 Query Block 中没有找到该表,或者发生冲突,那么 Hint 将会无效。请确保您使用的 Hint 是正确的,并且符合语法。
- 优化器的行为:OceanBase 数据库优化器是动态规划的,已经考虑了所有可能的最优路径(见文档片段 2)。因此,有时候即使指定了 Hint,优化器也可能认为原有的计划更好,从而忽略 Hint。
2. 计划缓存匹配规则是什么?是不是 SQL 文本完全一致才会命中缓存?
-
计划缓存匹配规则:并不是 SQL 文本完全一致才会命中缓存。实际上,当数据库接收到一条 SQL 请求后,首先会通过 fast parser 模块对 SQL 文本做一次快速参数化,将常量参数替换为通配符
?(如SELECT * FROM t1 WHERE c1 = 1被替换为SELECT * FROM t1 WHERE c1 = ?),然后使用这个参数化的 SQL 文本去匹配计划缓存中的记录(详见文档片段 5 和 9)。 - 因此,只要参数化后的 SQL 文本相同,就可以命中缓存。
3. 已经缓存了旧计划之后,新增 Hint 的同文本 SQL 会不会继续复用旧计划?
- 如果一个 SQL 在加入新的 Hint 后再次被执行,而之前的计划已经被缓存在计划缓存中,那么因为参数化后的 SQL 文本发生了变化(增加了 Hint),它将会被视为一个新的查询请求。在这种情况下,系统不会直接复用旧的执行计划,而是会重新生成一个新的执行计划并保存到计划缓存中。
4. 如果想让 hint 马上生效,除了重启租户,有什么清理单条 SQL 计划缓存的办法?
-
清理单条 SQL 的计划缓存:如果您希望使特定 SQL 的 Hint 立即生效,可以手动清理相关的计划缓存条目。具体的方法是使用
OCP或者OBProxy等管理工具来清除指定 SQL 的执行计划缓存。不过,目前 OceanBase 直接提供的命令行工具 obd 或 obshell 对于这种操作的支持有限,更推荐的做法是在 OCP 上进行相关操作。 - 此外,在某些版本中,可以通过执行一些内部命令或脚本来清理特定 SQL 的计划缓存,但这通常需要较高的权限且不建议非专业人员操作。建议您联系 OceanBase 支持团队获取具体的操作指南。
基于上述信息,您可以尝试以下步骤解决问题:
- 检查 Hint 的正确性:确保 Hint 的语法正确且适用场景正确。
- 查看 SQL 参数化后的文本:确认是否因 Hint 导致参数化后的 SQL 文本发生变化。
- 清理相关 SQL 的计划缓存:使用 OCP 或其他管理工具来清理特定 SQL 的执行计划缓存。
希望这些信息能够帮助到您!如有更多疑问,请随时告知。
检索到的文档如下: