TiDB 关联子查询及半连接的优化实践
内容提要
TiDB 针对子查询进行了多种优化以提升执行性能,包括半连接和关联子查询。TiDB 提供自动优化和 HINT 选项,半连接关注外表记录是否匹配内表,优化器可选择 Hash Join 或 Index Join。此外,TiDB 支持子查询去关联优化,减少重复执行,提高效率,但在数据量小的情况下可能效果不佳。
关键要点
-
TiDB 针对子查询进行了多种优化以提升执行性能,包括半连接和关联子查询。
-
TiDB 提供自动优化和 HINT 选项,半连接关注外表记录是否匹配内表。
-
优化器可选择 Hash Join 或 Index Join 来执行半连接。
-
TiDB 支持子查询去关联优化,减少重复执行,提高效率。
-
在数据量小的情况下,子查询去关联优化可能效果不佳。
-
半连接只关心外表记录是否在内表中有匹配,而不关心匹配记录的数量。
-
半连接可以通过 EXISTS 子查询、IN 子查询或直接转换为 JOIN 操作实现。
-
优化器在选择 Hash Join 时,子查询结果集大于外查询时,执行速度可能不及预期。
-
TiDB 提供 semi_join_rewrite() HINT 来改善优化器的选择范围。
-
在 Index Join 的情况下,外查询作为驱动表,子查询结果集小时,执行速度可能不佳。
-
关联子查询是与外部查询有关联的子查询,每次外部查询返回一行数据,内部查询执行一次。
-
TiDB 默认尝试进行子查询去关联,以提高执行效率。
-
在外部值较少的情况下,不解除关联依赖可能更有利于性能。
-
全局关闭子查询去关联可以通过将规则加入黑名单实现。
-
TiDB 针对半连接的优化可能在某些场景下未达到最佳性能,需使用 SEMI_JOIN_REWRITE() 进行调整。
延伸解读
半连接的执行效率
半连接(Semi Join)在处理外表和内表的匹配时,关注的是外表记录是否存在于内表中,而不关心匹配的数量。这种特性使得半连接在某些场景下能显著提高查询效率,尤其是在外表记录较多而内表记录较少的情况下。使用 EXISTS 或 IN 子查询可以实现半连接,但在内表匹配项较多时,性能可能会下降。
子查询去关联的优化策略
TiDB 默认尝试对子查询进行去关联优化,以减少重复执行,提高查询效率。然而,在数据量较小的情况下,去关联优化可能反而导致性能下降。因此,在设计查询时,开发者需要根据具体数据情况,灵活选择是否使用去关联优化。
HINT 的使用场景
TiDB 提供了多种 HINT 选项,如 semi_join_rewrite(),用于改善优化器的选择范围。合理使用 HINT 可以帮助优化器选择更高效的执行计划,尤其是在复杂查询中。开发者应关注执行计划的变化,适时调整 HINT,以达到最佳性能。
延伸问答
TiDB 如何优化子查询的执行性能?
TiDB 通过多种优化策略提升子查询的执行性能,包括半连接和关联子查询的优化,提供自动优化和 HINT 选项。
什么是半连接,TiDB 如何实现它?
半连接是一种只关心外表记录是否在内表中有匹配的连接操作,TiDB 可以通过 EXISTS 子查询、IN 子查询或直接转换为 JOIN 操作实现。
TiDB 中的子查询去关联优化有什么优势?
子查询去关联优化可以减少重复执行,提高执行效率,但在数据量小的情况下可能效果不佳。
在什么情况下 TiDB 的半连接优化可能效果不佳?
当子查询结果集大于外查询时,选择 Hash Join 可能导致执行速度不及预期,且在数据量小的情况下,去关联优化可能效果不佳。
TiDB 提供的 semi_join_rewrite() HINT 有什么作用?
semi_join_rewrite() HINT 可以改善优化器的选择范围,帮助选择更高效的执行方式,尤其在处理 EXISTS 子查询时。
关联子查询的特点是什么?
关联子查询与外部查询有关联,信息流双向,外部查询每行数据传递给子查询,且每次外部查询返回一行数据时,内部查询执行一次。