暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 19C 笛卡尔联接

原创 Asher.HU 2021-02-04
865


当一个或多个表对语句中的任何其他表没有任何连接条件时,数据库将使用笛卡尔连接

优化器将一个数据源的每一行与另一数据源的每一行连接在一起,从而创建两组数据集的笛卡尔积。因此,使用以下公式计算联接产生的总行数,其中,rs1是第一行集中rs2的行数和第二行集中的行数:

rs1 X rs2 = total rows in result set

 

 

9.3.5.1当优化器考虑笛卡尔联接时

仅在特定情况下,优化器才将笛卡尔联接用于两个行源。

通常,情况是以下情况之一:

  • 不存在加入条件  : 在某些情况下,优化器可能会选择两个表之间的公共过滤条件作为可能的连接条件。

    注意: 如果笛卡尔联接出现在查询计划中,则可能是由于无意中省略了联接条件引起的。通常,如果查询联接了n个表,则需要n -1个联接条件才能避免笛卡尔联接。

  • 笛卡尔联接是一种有效的方法。

    例如,优化器可能会决定生成两个非常小的表的笛卡尔积,它们都连接到同一个大表。

  • ORDERED提示指定一个表之前,其加入指定表。

 

9.3.5.2笛卡尔联接如何工作

笛卡尔联接使用嵌套FOR循环。

在较高级别上,笛卡尔联接的算法如下所示,其中ds1通常是较小的数据集,而ds2较大的数据集是:

FOR ds1_row IN ds1 LOOP
  FOR ds2_row IN ds2 LOOP
    output ds1_row and ds2_row
  END LOOP
END LOOP

示例9-18笛卡尔联接

在此示例中,用户打算对employeesdepartments执行内部联接,但意外地放弃了联接条件:

SELECT e.last_name, d.department_name
FROM   employees e, departments d

执行计划如下:

--------------------------------------------------------------------------------
| Id| Operation              | Name        | Rows  | Bytes |Cost (%CPU)| Time  |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT       |             |       |       |11 (100)|          |
| 1 |  MERGE JOIN CARTESIAN  |             |  2889 | 57780 |11   (0)| 00:00:01 |
| 2 |   TABLE ACCESS FULL    | DEPARTMENTS |    27 |   324 | 2   (0)| 00:00:01 |
| 3 |   BUFFER SORT          |             |   107 |   856 | 9   (0)| 00:00:01 |
| 4 |    INDEX FAST FULL SCAN| EMP_NAME_IX |   107 |   856 | 0   (0)|          |
--------------------------------------------------------------------------------

在上述计划的步骤1中,CARTESIAN关键字指示存在笛卡尔连接。行数(2889)是27和107的乘积。

在步骤3中,该BUFFER SORT操作指示数据库正在将通过扫描emp_name_ix从SGA 获得的数据块复制到PGA。此策略避免了对数据库缓冲区高速缓存中相同块的多次扫描,这将生成许多逻辑读取并允许资源争用。

 

9.3.5.3笛卡尔联接控件

ORDERED提示指示优化器按照表在FROM子句中出现的顺序连接表通过强制没有直接连接的两个行源之间的联接,优化器必须执行笛卡尔联接。

示例9-19 ORDERED提示

在以下示例中,ORDERED提示指示优化器加入employeeslocations,但没有加入条件连接这两个行源:

SELECT /*+ORDERED*/ e.last_name, d.department_name, l.country_id, l.state_province
FROM   employees e, locations l, departments d
WHERE  e.department_id = d.department_id
AND    d.location_id = l.location_id

以下执行计划显示了locations(步骤6)和employees(步骤4)之间的笛卡尔乘积(步骤3 ),然后将其连接到departments表(步骤2):

--------------------------------------------------------------------------------
| Id| Operation             | Name        | Rows  | Bytes |Cost (%CPU)|Time    |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT      |             |       |       | 37 (100)|          |
|*1 |  HASH JOIN            |             |   106 |  4664 | 37   (6)| 00:00:01 |
| 2 |   TABLE ACCESS FULL   | DEPARTMENTS |    27 |   513 |  2   (0)| 00:00:01 |
| 3 |   MERGE JOIN CARTESIAN|             |  2461 | 61525 | 34   (3)| 00:00:01 |
| 4 |    TABLE ACCESS FULL  | EMPLOYEES   |   107 |  1177 |  2   (0)| 00:00:01 |
| 5 |    BUFFER SORT        |             |    23 |   322 | 32   (4)| 00:00:01 |
| 6 |     TABLE ACCESS FULL | LOCATIONS   |    23 |   322 |  0   (0)|          |
--------------------------------------------------------------------------------

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论