表连接操作
嵌套循环连接 (nested loops)
- 首先选择一张表作为连接的驱动表 (driving table),这张表也成为外部表 (outer table)。由驱动表进行驱动连接的表称为被驱动表,也叫内部表 (inner table)。
- 提取驱动表中符合条件的记录,逐行与被驱动表的连接列进行关联查询符合条件的记录。
适用于查询的选择性强、约束性高并且只返回小部分记录的结果集。通常要求驱动表的记录较少,且被驱动表连接列有唯一索引或者选择性强的非唯一索引。
连接列、where 条件中的字段要做好索引,避免使用 select *。
哈希连接 (hash join)
- 构建阶段:优化器首先选择一张小表作为驱动表,运用哈希函数对连接列进行计算产生一张哈希表。
- 探测阶段:优化器对被驱动表的连接列运用同样的哈希函数计算得到的结果与前面形成的哈希表进行探测返回符合条件的记录。这个阶段中如果被驱动表的连接列的值没有与驱动表连接列的值相等的话,那么这些记录将会被丢弃而不进行探测。
使用场景:处理数据量大、无序、无索引的输入数据,比如复杂运算的中间结果集
局限:只能用于等值连接;连接条件要有一定的区分度
索引应该建立在非连接列上。
通过 where 条件筛选、select 只选择必需的字段可以减少哈希表的空间占用,帮助提高性能。
排序-合并连接 (sort merge join)
两张表都需要按照连接列排好序。排序完后形成的结果集再互相进行合并连接提取符合条件的记录。相比嵌套循环连接,排序合并连接比较适用于返回大数据量的结果。
排序合并连接在数据表预先排序好的情况下效率是非常高的,也比较适用于非等值连接的情况,比如 > 、>= 、<= 等情况下的连接(哈希连接只适用于等值连接)。由于排序操作的开销是非常消耗资源的,当结果集很大时排序合并连接的性能很差。
索引应该建立在非连接列上。