优化器如何评估和选择join算法

有没有关于优化器对于 join算法开销评估和选择这方面的介绍

1.1.优化器什么时候选择Hash Join

一般情况下,当需要join的数据量比较大时(或者需要join的小表的比例很大),优化器会考虑hash join,而且需要是等值连接。

较小的数据集使用比较少的内存物化数据,hash join性能最好。 在这种情况下,连接成本只是对两个数据集进行一次读取。因为哈希表在内存中,所以数据库可以不需要通过锁访问数据行。 此技术通过避免重复锁存和读取数据库缓冲区缓存中的块的必要性来减少逻辑 I/O。

如果数据集较大,内存不足以存放,则数据库对数据源进行分区,并逐个分区进行连接。 这会使用大量排序区域内存和临时表空间的 I/O。 这种方法仍然有高效场景,尤其是当数据库使用并行查询时。

1.2 如何控制优化器使用Hash Join

最直接的控制手段就是通过hint指定连接算法,可以通过使用USE_HASH 指示优化器使用Hash Join算法。通常还需要配合使用LEADING hint,因为指定Hash Join算法之后计划的成本可能不是最低的,会被其他成本更低的计划(连接次序不同)覆盖。USE_HASH 的参数为连接的右表。

2.1 优化器什么时候选择Merge Join

Merge Join同样适合大数据量的连接,如果连接两侧的数据源都是无序的,或者连接条件是非等值连接,优化器不会选择Merge Join算法,而是选择其他连接算法。否则优化器会尝试生成Merge Join计划,并通过计划成本来选择合适的连接算法。

2.2 如何控制优化器使用Merge Join

最直接的控制手段就是通过hint指定连接算法,可以通过使用USE_MERGE 指示优化器使用Merge Join算法。通常还需要配合使用LEADING hint,因为指定Merge Join算法之后计划的成本可能不是最低的,会被其他成本更低的计划(连接次序不同)覆盖。USE_MERGE 的参数为连接的右表。

3.1 优化器什么时候选择Nested Loops Joins

当数据库连接小的数据集与大的数据集,并且对于大的数据集,满足连接条件的数据量很少或者只需要输出满足条件的第一行时,嵌套循环连接很有用。

通常,嵌套循环连接在连接条件上有索引并且驱动表为小表时效果最好。 如果数据源只有一行,如对主键值的等值过滤查找(例如,WHERE id=101),则连接是一个简单的查找。 优化器总是尝试将最小的数据源放在左侧,使其成为驱动表。

有很多因素会影响优化器决定是否使用嵌套循环。 例如,hint、连接条件是否有等值连接条件、连接条件是否存在索引以及驱动表是否最多输出一行数据。如果查询上存在Nested Loop Join控制相关的hint,优化器会完全按照hint的指示决定是否使用Nested Loops Joins。在没有hint指示的情况下,如果连接条件存在等值连接条件,并且连接条件上面没有匹配的索引,同时驱动表输出多行数据,那么优化器一定不会选择Nested Loops Join,否则优化器会尝试生成Nested Loops Join计划并计算计划的成本。最终通过成本决定是否使用Nested Loops Join。

此外,如果连接条件不存在等值连接,或者没有连接条件,优化器一定会选择使用Nested Loops Joins,因为优化器没有其他可选的算法。

3.2 如何控制优化器使用Nested Loops Join

最直接的控制手段就是通过hint指定连接算法,可以通过使用USE_NL 指示优化器使用Nested Loops Join算法。通常还需要配合使用LEADING hint,因为指定Nested Loops Join算法之后计划的成本可能不是最低的,会被其他成本更低的计划(连接次序不同)覆盖。USE_NL 的参数为连接的右表。

1 个赞

有量化的公式吗

目前没有