笛卡尔积和NEST LOOP产生的影响

简介: 原创 转载请注明出处 SQL 性能分析,笛卡尔积和NEST LOOP SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'iostats last')); PLAN_TAB...

原创 转载请注明出处

SQL 性能分析,笛卡尔积和NEST LOOP

SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'iostats last'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5tq3dm3w602k0, child number 0
-------------------------------------

select count(*) total
  from (select distinct (c.customer_id),
                        c.risk_level risk,
                        c.real_name cusname,
                        c.gender gender,
                        to_char(c.birthday, 'yyyy-mm-dd') birthday,
                        c.certi_code certicode,
                        cm.policy_code policycode,
                        cm.discount_prem prem,
                        to_char(cm.accept_date, 'yyyy-mm-dd') accept_date
          from t_customer         c,
               t_certi_type       ct,
               t_contract_master  cm,
               t_contract_product cp
         where exists
         (select *
                  from (select t.applicant_id customer_id
                          from (select cm1.applicant_id, cm1.accept_date
                                  from t_contract_master cm1
                                 where not exists
                                 (select cm2.applicant_id
                                          from t_contract_master cm2
                                         where cm1.applicant_id =
                                               cm2.applicant_id
                                           and (cm2.accept_date                                                to_date('2009-10-01',
                                                        'yyyy-mm-dd')))) t
                         where t.accept_date >=
                               to_date('2009-10-01', 'yyyy-mm-dd')
                           and t.accept_date                                to_date('2009-12-31', 'yyyy-mm-dd') + 1) temp
                 where temp.customer_id = c.customer_id)
           and c.certi_type = ct.type_id
           and (c.customer_id = cm.applicant_id or
               c.customer_id = cp.insured_1)
           and cm.policy_id = cp.policy_id
           and c.risk_level = 'D'
           and cm.accept_date > = to_date('2009-10-01', 'yyyy-mm-dd')
           and cm.accept_date                     
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 907659101

---------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name                          | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------------------------------------------------
|   1 |  SORT AGGREGATE                    |                               |      1 |      1 |      1 |00:21:51.83 |     606M|    409 |
|   2 |   VIEW                             |                               |      1 |      1 |   5295 |00:21:51.85 |     606M|    409 |
|   3 |    HASH UNIQUE                     |                               |      1 |      1 |   5295 |00:21:51.84 |     606M|    409 |
|   4 |     NESTED LOOPS                   |                               |      1 |      1 |   6307 |01:51:27.91 |     606M|    409 |
|   5 |      MERGE JOIN CARTESIAN          |                               |      1 |      1 |    303M|00:20:12.96 |   15644 |    374 |

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   6 |       NESTED LOOPS                 |                               |      1 |      1 |   5282 |00:00:02.51 |   15445 |    374 |
|*  7 |        HASH JOIN ANTI              |                               |      1 |      1 |   5282 |00:00:00.08 |    4879 |      0 |
|   8 |         TABLE ACCESS BY INDEX ROWID| T_CONTRACT_MASTER             |      1 |   3379 |   5631 |00:00:00.05 |    1038 |      0 |
|*  9 |          INDEX RANGE SCAN          | IDX_CONTRACT_MASTER__ACP_DATE |      1 |   3379 |   5631 |00:00:00.01 |      17 |      0 |
|* 10 |         TABLE ACCESS FULL          | T_CONTRACT_MASTER             |      1 |  43806 |  32177 |00:00:00.06 |    3841 |      0 |
|* 11 |        TABLE ACCESS BY INDEX ROWID | T_CUSTOMER                    |   5282 |      1 |   5282 |00:00:00.66 |   10566 |    374 |
|* 12 |         INDEX UNIQUE SCAN          | PK_T_CUSTOMER                 |   5282 |      1 |   5282 |00:00:00.17 |    5284 |     26 |
|  13 |       BUFFER SORT                  |                               |   5282 |  57406 |    303M|00:10:06.48 |     199 |      0 |
|  14 |        INDEX FAST FULL SCAN        | UNI_CONTRACT_PRODUCT__PRONUM  |      1 |  57406 |  57406 |00:00:00.06 |     199 |      0 |
|* 15 |      TABLE ACCESS BY INDEX ROWID   | T_CONTRACT_MASTER             |    303M|      1 |   6307 |01:29:21.72 |     606M|     35 |
|* 16 |       INDEX UNIQUE SCAN            | PK_T_CONTRACT_MASTER          |    303M|      1 |    303M|00:39:35.06 |     303M|      0 |

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   7 - access("CM1"."APPLICANT_ID"="CM2"."APPLICANT_ID")
   9 - access("CM1"."ACCEPT_DATE">=TO_DATE('2009-10-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND
              "CM1"."ACCEPT_DATE"  10 - filter("CM2"."ACCEPT_DATE"  11 - filter("C"."RISK_LEVEL"='D')
  12 - access("CM1"."APPLICANT_ID"="C"."CUSTOMER_ID")

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  15 - filter(("CM"."ACCEPT_DATE">=TO_DATE('2009-10-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND
              "CM"."ACCEPT_DATE"              ("C"."CUSTOMER_ID"="CM"."APPLICANT_ID" OR
              "C"."CUSTOMER_ID"="CP"."INSURED_1")))
  16 - access("CM"."POLICY_ID"="CP"."POLICY_ID")


49 rows selected.

语句在15步的时候耗用的大量的时间,应为NEST LOOP会去匹配先前结果中的每一行,而先前的得出行数是303M行,
这个结果就是由于MERGE JOIN CARTESIAN产生了笛卡尔积。
连接条件中出现了笛卡尔积,原因是连接条件不足,t_customer 没有和所有的表进行关联,
形如
select * from test,test2的语句也就是笛卡尔积,A表中的每一行会和B表中的所有行进行一次匹配,
如果TEST有3条数据,TEST2有3条数据就会形成3*3 9条数据。
此外这个语句在使用索引和访问方式都比较合理,所以要改善性能必须去掉笛卡尔积产生的大量结果集,谢谢!

相关文章
|
8天前
|
SQL Java 数据库
笛卡尔积语句排查
笛卡尔积语句排查
|
7月前
kettle开发篇-记录关联(笛卡尔积)
kettle开发篇-记录关联(笛卡尔积)
264 0
|
关系型数据库 MySQL
left join、right join和join,傻傻分不清?
真的是一张图道清所有join的区别啊,可惜我还是看不懂,可能人比较懒,然后基本一个left join给我就是够用的了,所以就没怎么去仔细研究了,但是现实还是逼我去搞清楚,索性自己动手,总算理解图中的含义了,下面就听我一一道来。
109 1
|
数据库
子查询与内连接查询区别(效率上,连接查询高于子查询)、左连接以及连接的原理,还有内连接与左连接的区别
子查询与内连接查询区别(效率上,连接查询高于子查询)、左连接以及连接的原理,还有内连接与左连接的区别
1138 0
子查询与内连接查询区别(效率上,连接查询高于子查询)、左连接以及连接的原理,还有内连接与左连接的区别
|
SQL 存储 数据库
工作总结之因为笛卡尔积问题写SQL搞了半天[害](附笛卡尔积总结)
在关系数据库中,一个查询往往会涉及多个表,因为很少有数据库只有一个表,而如果大多查询只涉及到一个表的,那么那个表也往往低于第三范式,存在大量冗余和异常。
323 0
工作总结之因为笛卡尔积问题写SQL搞了半天[害](附笛卡尔积总结)
|
SQL 关系型数据库 MySQL
SQL内连接、外连接、全连接、交叉连接、自连接、自然连接区别
本文是博主学习SQL的记录,希望对大家有所帮助
1153 0
SQL内连接、外连接、全连接、交叉连接、自连接、自然连接区别
|
关系型数据库 MySQL BI
mysql中left join的误解及笛卡尔积解释
mysql中left join的误解及笛卡尔积解释
608 0
mysql中left join的误解及笛卡尔积解释
|
SQL 关系型数据库 MySQL
Semi-join使用条件,派生表优化 (3)—mysql基于规则优化(四十六)
Semi-join使用条件,派生表优化 (3)—mysql基于规则优化(四十六)
|
存储 关系型数据库 MySQL
mysql加强(4)~多表查询:笛卡尔积、消除笛卡尔积操作(等值、非等值连接),内连接(隐式连接、显示连接)、外连接、自连接
mysql加强(4)~多表查询:笛卡尔积、消除笛卡尔积操作(等值、非等值连接),内连接(隐式连接、显示连接)、外连接、自连接
910 0
mysql加强(4)~多表查询:笛卡尔积、消除笛卡尔积操作(等值、非等值连接),内连接(隐式连接、显示连接)、外连接、自连接
|
SQL 存储 关系型数据库
【教奶奶学SQL】(task3)复杂查询(视图 | 子查询 | 谓词 | Case)
单从表面上看起来这个语句是和正常的从数据表中查询数据是完全相同的,但其实我们操作的是一个视图。所以从SQL的角度来说操作视图与操作表看起来是完全相同的,那么为什么还会有视图的存在呢?视图到底是什么?视图与表有什么不同呢?
275 0
【教奶奶学SQL】(task3)复杂查询(视图 | 子查询 | 谓词 | Case)