今天收到了一位网友的SQL优化请求,
这个语句已经跑了快10天了,还没出来,这位网友已经开始怀疑数据是否存在问题,存储、网络哪方面肯定存在异常。
-
INSERT
/*+append*/
INTO
B nologging
-
SELECT
DISTINCT
'201707 AS bill_mon,t.product_id,user_nbr,node_id ,0 if_zeng,t1.product_name FROM A t
-
,bic.WASU_CP_Product_Type t1
-
WHERE to_char(etl_dt,'yyyymm
')='
201707
' and to_char(effective_dt,'
yyyymm
')<='
201706
'
-
and t.product_id=t1.product_id(+)
-
and NOT EXISTS(SELECT 1 FROM A t2
-
WHERE t2.node_id=t.node_id and t.user_nbr=t2.user_nbr
-
and t.product_id=t2.product_id
-
AND to_char(etl_dt,'yyyymm
')='
201706
' and to_char(effective_dt,'
yyyymm
')<='
201705
2、优化SQL第一步,获取执行计划
请使用以下语句获取执行计划
-
explain plan for
-
INSERT
/*+append*/
INTO
B nologging
-
SELECT
DISTINCT
'201707 AS bill_mon,t.product_id,user_nbr,node_id ,0 if_zeng,t1.product_name FROM A t
-
,bic.WASU_CP_Product_Type t1
-
WHERE to_char(etl_dt,'yyyymm
')='
201707
' and to_char(effective_dt,'
yyyymm
')<='
201706
'
-
and t.product_id=t1.product_id(+)
-
and NOT EXISTS(SELECT 1 FROM A t2
-
WHERE t2.node_id=t.node_id and t.user_nbr=t2.user_nbr
-
and t.product_id=t2.product_id
-
AND to_char(etl_dt,'yyyymm
')='
201706
' and to_char(effective_dt,'
yyyymm
')<='
201705;
-
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种表的连接方法,原理、
适用场景和优缺点各是什么,请见下回分解???