微课sql优化(12)、表的连接方法(1)-帮助网友优化报表SQL

1、问题来了

今天收到了一位网友的SQL优化请求, 这个语句已经跑了快10天了,还没出来,这位网友已经开始怀疑数据是否存在问题,存储、网络哪方面肯定存在异常。
  1. INSERT /*+append*/   INTO   B nologging
  2.         SELECT   DISTINCT   '201707 AS bill_mon,t.product_id,user_nbr,node_id ,0 if_zeng,t1.product_name FROM A t
  3.     ,bic.WASU_CP_Product_Type t1
  4.     WHERE to_char(etl_dt,'yyyymm ')=' 201707 ' and to_char(effective_dt,' yyyymm ')<=' 201706 '
  5.       and t.product_id=t1.product_id(+)
  6.       and NOT EXISTS(SELECT 1 FROM A t2 
  7.     WHERE t2.node_id=t.node_id and t.user_nbr=t2.user_nbr
  8.       and t.product_id=t2.product_id
  9.       AND to_char(etl_dt,'yyyymm ')=' 201706 ' and to_char(effective_dt,' yyyymm ')<=' 201705

2、优化SQL第一步,获取执行计划

请使用以下语句获取执行计划
  1. explain plan for
  2. INSERT /*+append*/   INTO  B nologging
  3.         SELECT   DISTINCT   '201707 AS bill_mon,t.product_id,user_nbr,node_id ,0 if_zeng,t1.product_name FROM A t
  4.     ,bic.WASU_CP_Product_Type t1
  5.     WHERE to_char(etl_dt,'yyyymm ')=' 201707 ' and to_char(effective_dt,' yyyymm ')<=' 201706 '
  6.       and t.product_id=t1.product_id(+)
  7.       and NOT EXISTS(SELECT 1 FROM A t2 
  8.     WHERE t2.node_id=t.node_id and t.user_nbr=t2.user_nbr
  9.       and t.product_id=t2.product_id
  10.       AND to_char(etl_dt,'yyyymm ')=' 201706 ' and to_char(effective_dt,' yyyymm ')<=' 201705;
  11. SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

以下是该网友发过来的执行计划。

3、优化SQL第二步, 分析执行计划

使用之前课程讲解的光标化分析执行计划步骤,

4、优化SQL第三步,分析操作关系

练习:    请问步骤3和步骤4、 步骤5和步骤6、 步骤2和步骤5,分别是之间讲过的,单独型、非关联型、关联型哪种?

5、优化SQL第四步,如何优化?

初步怀疑表BIC_ORDER_ALL_LOG统计信息过旧,
1、查下统计信息准不 
select count(1) from bic_order_all_log_z;

select count(1) from bic_order_all_log_z where  to_char(etl_dt,'yyyymm ')=' 201707 ' and to_char(effective_dt,' yyyymm ')<=' 201706 ';

通过以上查询结果,可以判断该表统计信息过旧,造成CBO生成执行计划异常。

优化方法一、从新收集统计信息

本来计划让这位网友从新收集统计信息,首先查看所查询表的统计信息,
select owner,table_name,num_rows,last_analyzed from dba_tables where table_name='表名' and owner='用户';
select owner,table_name,num_distinct from dba_tab_columns where table_name='表名' and owner='用户';
select count(1) from 表名;
统计信息一直未反馈, 这位网友是位数据库开发,无法进行数据库统计信息收集。
练习:     现在问题来了,如果是您,如何从新收集该语句所查询表的统计信息?

优化方法二、hint法

优化后语句
SELECT '201707' AS bill_mon,t.product_id ,t1.product_name, t.user_nbr ,0 as if_tui,t.node_id
      FROM bic.BIC_ORDER_all_LOG_Z t ,bic.WASU_CP_Product_Type t1
     WHERE   t.product_id=t1.product_id(+)
     AND to_char(etl_dt,'yyyymm')='201707' 
     and to_char(effective_dt,'yyyymm')<='201706'
     AND NOT EXISTS(SELECT /*+ use_hash(t, t2)*/1
    FROM bic.BIC_ORDER_all_LOG_Z t2 
     WHERE to_char(etl_dt,'yyyymm')='201708' and to_char(effective_dt,'yyyymm')<='201707'
     AND t.user_nbr=t2.user_nbr AND t.product_id=t2.product_id AND t.node_id=t2.node_id);

6、 优化SQL第五步,判定优化后SQL执行计划

7、 优化SQL第六步,优化后执行时间

     :   现在,多长时间出结果?
回复:几分钟,

8、表的连接方法

SQL语句优化前10天查询不出来,优化后几分钟出结果,通过以上优化案例,引出我们下面要讨论的内容,表连接的方式有哪几种:
  • Nested Loops Join
  • Hash Join
  • Sort Merge Join
  • Cartesian Join
以上4种表的连接方法,原理、 适用场景和优缺点各是什么,请见下回分解???
请使用浏览器的分享功能分享到微信等