视图合并、hash join连接列数据分布不均匀引发的惨案
表大小
SQL> select count(*) from agent.TB_AGENT_INFO;
COUNT(*)
----------
1751
SQL> select count(*) from TB_CHANNEL_INFO ;
COUNT(*)
----------
1807
SQL> select count(*) from TB_USER_CHANNEL;
COUNT(*)
----------
7269
SQL> select count(*) from OSS_USER_STATION;
COUNT(*)
----------
2149
SQL> select count(*) from tb_user_zgy ;
COUNT(*)
----------
43
SQL> select count(*) from act.tb_user_agent_relat;
COUNT(*)
----------
29612
SQL> select count(*) from agent.base_data_user_info ;
COUNT(*)
----------
30005
SQL> select count(*) from agent.base_data_invest_info;
COUNT(*)
----------
3530163
慢的sql
select a.city,
a.agent_id,
a.username,
a.real_name,
phone,
zgy_name,
login_count,
user_count,
count(distinct b.invest_id) user_invested,
sum(b.order_amount / 100) invest_amount
from (select a.city,
a.agent_id,
a.username,
a.real_name, -- 业主姓名
a.phone, -- 业主手机号
d.real_name zgy_name, -- 所属专管员
count(distinct case
when c.str_day <= '20160821' then
c.login_name
end) login_count,
count(distinct case
when c.str_day <= '20160821' then
decode(c.status, 1, c.invest_id, null)
end) user_count
from (select agent_id, city, username, real_name, phone
from agent.TB_AGENT_INFO
where agent_id in
(SELECT agent_id
FROM (SELECT distinct *
FROM TB_CHANNEL_INFO t
START WITH t.CHANNEL_ID in
(select CHANNEL_ID
from TB_USER_CHANNEL
where USER_ID = 596)
CONNECT BY PRIOR
t.CHANNEL_ID = t.PARENT_CHANNEL_ID)
WHERE agent_id IS NOT NULL)) a
left join oss_user_station e
on a.agent_id = e.agent_id
and e.user_type = 0
left join tb_user_zgy d
on e.username = d.username
left join act.tb_user_agent_relat c
on a.agent_id = c.agent_id
group by a.city,
a.username,
a.real_name,
a.phone,
d.real_name,
a.agent_id) a
left join (select invest_id, order_amount, agent_id, str_day
from agent.base_data_invest_info
where str_day >= '20150801' and str_day<='20160821') b
on a.agent_id = b.agent_id
group by a.city,
a.agent_id,
a.username,
a.real_name,
a.phone,
a.zgy_name,
a.login_count,
a.user_count
这个查询可以看成两部分,第一部分一堆小表关联的a和唯一的一个大表再做关联
man
----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 55M| 6616M| | 3934K (1)| 13:06:52 |
| 1 | HASH GROUP BY | | 55M| 6616M| | 3934K (1)| 13:06:52 |
| 2 | VIEW | VW_DAG_1 | 55M| 6616M| | 3934K (1)| 13:06:52 |
| 3 | HASH GROUP BY | | 55M| 6301M| 7681M| 3934K (1)| 13:06:52 |
| 4 | VIEW | VM_NWVW_0 | 55M| 6301M| | 2456K (1)| 08:11:15 |
| 5 | SORT GROUP BY | | 55M| 10G| 11G| 2456K (1)| 08:11:15 |
|* 6 | HASH JOIN RIGHT OUTER | | 55M| 10G| | 21643 (2)| 00:04:20 |
| 7 | TABLE ACCESS FULL | TB_USER_AGENT_RELAT | 27937 | 1200K| | 102 (0)| 00:00:02 |
|* 8 | HASH JOIN OUTER | | 3374K| 511M| | 21392 (1)| 00:04:17 |
|* 9 | HASH JOIN SEMI | | 1712 | 188K| | 2007 (1)| 00:00:25 |
|* 10 | HASH JOIN RIGHT OUTER | | 1712 | 173K| | 32 (0)| 00:00:01 |
| 11 | TABLE ACCESS FULL | TB_USER_ZGY | 43 | 903 | | 3 (0)| 00:00:01 |
|* 12 | HASH JOIN RIGHT OUTER | | 1712 | 138K| | 29 (0)| 00:00:01 |
|* 13 | TABLE ACCESS FULL | OSS_USER_STATION | 1075 | 25800 | | 6 (0)| 00:00:01 |
| 14 | TABLE ACCESS FULL | TB_AGENT_INFO | 1712 | 98K| | 23 (0)| 00:00:01 |
| 15 | VIEW | VW_NSO_1 | 16271 | 143K| | 1975 (1)| 00:00:24 |
|* 16 | VIEW | | 16271 | 143K| | 1975 (1)| 00:00:24 |
| 17 | HASH UNIQUE | | 16271 | 8882K| 10M| 1975 (1)| 00:00:24 |
|* 18 | CONNECT BY WITHOUT FILTERING (UNIQUE)| | | | | | |
|* 19 | HASH JOIN RIGHT SEMI | | 530 | 146K| | 29 (0)| 00:00:01 |
|* 20 | TABLE ACCESS FULL | TB_USER_CHANNEL | 600 | 7800 | | 7 (0)| 00:00:01 |
| 21 | TABLE ACCESS FULL | TB_CHANNEL_INFO | 1807 | 476K| | 22 (0)| 00:00:01 |
| 22 | TABLE ACCESS FULL | TB_CHANNEL_INFO | 1807 | 476K| | 22 (0)| 00:00:01 |
|* 23 | TABLE ACCESS FULL | BASE_DATA_INVEST_INFO | 3374K| 148M| | 19375 (1)| 00:03:53 |
----------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access("AGENT_ID"="C"."AGENT_ID"(+))
8 - access("AGENT_ID"="AGENT_ID"(+))
9 - access("AGENT_ID"="AGENT_ID")
10 - access("C"."USERNAME"="D"."USERNAME"(+))
12 - access("AGENT_ID"="C"."AGENT_ID"(+))
13 - filter("C"."USER_TYPE"(+)=0)
16 - filter("AGENT_ID" IS NOT NULL)
18 - access("T"."PARENT_CHANNEL_ID"=PRIOR "T"."CHANNEL_ID")
19 - access("T"."CHANNEL_ID"="CHANNEL_ID")
20 - filter("USER_ID"=596)
23 - filter("STR_DAY"(+)>='20150801' AND "STR_DAY"(+)<='20160821')
尝试单独跑 a,很快
(select a.city,
a.agent_id,
a.username,
a.real_name, -- 业主姓名
a.phone, -- 业主手机号
d.real_name zgy_name, -- 所属专管员
count(distinct case
when c.str_day <= '20160821' then
c.login_name
end) login_count,
count(distinct case
when c.str_day <= '20160821' then
decode(c.status, 1, c.invest_id, null)
end) user_count
from (select agent_id, city, username, real_name, phone
from agent.TB_AGENT_INFO
where agent_id in
(SELECT agent_id
FROM (SELECT distinct *
FROM TB_CHANNEL_INFO t
START WITH t.CHANNEL_ID in
(select CHANNEL_ID
from TB_USER_CHANNEL
where USER_ID = 596)
CONNECT BY PRIOR
t.CHANNEL_ID = t.PARENT_CHANNEL_ID)
WHERE agent_id IS NOT NULL)) a
left join oss_user_station e
on a.agent_id = e.agent_id
and e.user_type = 0
left join tb_user_zgy d
on e.username = d.username
left join act.tb_user_agent_relat c
on a.agent_id = c.agent_id
group by a.city,
a.username,
a.real_name,
a.phone,
d.real_name,
a.agent_id) a
单独跑a很快,和b合在一起就很慢,那么怀疑是由于视图合并,导致了a内部的表提前去和b关联,引发了性能问题。
尝试禁止视图合并可以使用rownum>0,或no_merge hint
select a.city,
a.agent_id,
a.username,
a.real_name,
phone,
zgy_name,
login_count,
user_count,
count(distinct b.invest_id) user_invested,
sum(b.order_amount / 100) invest_amount
from (select * from (select a.city,
a.agent_id,
a.username,
a.real_name, -- 业主姓名
a.phone, -- 业主手机号
d.real_name zgy_name, -- 所属专管员
count(distinct case
when c.str_day <= '20160821' then
c.login_name
end) login_count,
count(distinct case
when c.str_day <= '20160821' then
decode(c.status, 1, c.invest_id, null)
end) user_count
from (select agent_id, city, username, real_name, phone
from agent.TB_AGENT_INFO
where agent_id in
(SELECT agent_id
FROM (SELECT distinct *
FROM TB_CHANNEL_INFO t
START WITH t.CHANNEL_ID in
(select CHANNEL_ID
from TB_USER_CHANNEL
where USER_ID = 596)
CONNECT BY PRIOR
t.CHANNEL_ID = t.PARENT_CHANNEL_ID)
WHERE agent_id IS NOT NULL)) a
left join oss_user_station e
on a.agent_id = e.agent_id
and e.user_type = 0
left join tb_user_zgy d
on e.username = d.username
left join act.tb_user_agent_relat c
on a.agent_id = c.agent_id
group by a.city,
a.username,
a.real_name,
a.phone,
d.real_name,
a.agent_id) where rownum>0)a
left join (select invest_id, order_amount, agent_id, str_day
from agent.base_data_invest_info
where str_day >= '20150801' and str_day<='20160821') b
on a.agent_id = b.agent_id
group by a.city,
a.agent_id,
a.username,
a.real_name,
a.phone,
a.zgy_name,
a.login_count,
a.user_count
kuai
-----------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 823M| 96G| | 23M (1)| 78:59:52 |
| 1 | HASH GROUP BY | | 823M| 96G| | 23M (1)| 78:59:52 |
| 2 | VIEW | VW_DAG_0 | 823M| 96G| | 23M (1)| 78:59:52 |
| 3 | HASH GROUP BY | | 823M| 98G| 112G| 23M (1)| 78:59:52 |
|* 4 | HASH JOIN OUTER | | 823M| 98G| 26M| 41358 (6)| 00:08:17 |
| 5 | VIEW | | 259K| 23M| | 11090 (1)| 00:02:14 |
| 6 | COUNT | | | | | | |
|* 7 | FILTER | | | | | | |
| 8 | VIEW | | 259K| 23M| | 11090 (1)| 00:02:14 |
| 9 | SORT GROUP BY | | 259K| 38M| 41M| 11090 (1)| 00:02:14 |
|* 10 | HASH JOIN | | 259K| 38M| | 2111 (1)| 00:00:26 |
|* 11 | VIEW | | 16271 | 143K| | 1975 (1)| 00:00:24 |
| 12 | HASH UNIQUE | | 16271 | 8882K| 10M| 1975 (1)| 00:00:24 |
|* 13 | CONNECT BY WITHOUT FILTERING (UNIQUE)| | | | | | |
|* 14 | HASH JOIN RIGHT SEMI | | 530 | 146K| | 29 (0)| 00:00:01 |
|* 15 | TABLE ACCESS FULL | TB_USER_CHANNEL | 600 | 7800 | | 7 (0)| 00:00:01 |
| 16 | TABLE ACCESS FULL | TB_CHANNEL_INFO | 1807 | 476K| | 22 (0)| 00:00:01 |
| 17 | TABLE ACCESS FULL | TB_CHANNEL_INFO | 1807 | 476K| | 22 (0)| 00:00:01 |
|* 18 | HASH JOIN OUTER | | 27937 | 4037K| | 134 (0)| 00:00:02 |
|* 19 | HASH JOIN RIGHT OUTER | | 1712 | 173K| | 32 (0)| 00:00:01 |
| 20 | TABLE ACCESS FULL | TB_USER_ZGY | 43 | 903 | | 3 (0)| 00:00:01 |
|* 21 | HASH JOIN RIGHT OUTER | | 1712 | 138K| | 29 (0)| 00:00:01 |
|* 22 | TABLE ACCESS FULL | OSS_USER_STATION | 1075 | 25800 | | 6 (0)| 00:00:01 |
| 23 | TABLE ACCESS FULL | TB_AGENT_INFO | 1712 | 98K| | 23 (0)| 00:00:01 |
| 24 | TABLE ACCESS FULL | TB_USER_AGENT_RELAT | 27937 | 1200K| | 102 (0)| 00:00:02 |
|* 25 | TABLE ACCESS FULL | BASE_DATA_INVEST_INFO | 3374K| 109M| | 19375 (1)| 00:03:53 |
-----------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("A"."AGENT_ID"="AGENT_ID"(+))
7 - filter(ROWNUM>0)
10 - access("AGENT_ID"="AGENT_ID")
11 - filter("AGENT_ID" IS NOT NULL)
13 - access("T"."PARENT_CHANNEL_ID"=PRIOR "T"."CHANNEL_ID")
14 - access("T"."CHANNEL_ID"="CHANNEL_ID")
15 - filter("USER_ID"=596)
18 - access("AGENT_ID"="C"."AGENT_ID"(+))
19 - access("C"."USERNAME"="D"."USERNAME"(+))
21 - access("AGENT_ID"="C"."AGENT_ID"(+))
22 - filter("C"."USER_TYPE"(+)=0)
25 - filter("STR_DAY"(+)>='20150801' AND "STR_DAY"(+)<='20160821')
用no_merge hint禁止视图合并也可以
select a.city,
a.agent_id,
a.username,
a.real_name,
phone,
zgy_name,
login_count,
user_count,
count(distinct b.invest_id) user_invested,
sum(b.order_amount / 100) invest_amount
from (select /*+ no_merge */
a.city,
a.agent_id,
a.username,
a.real_name, -- 业主姓名
a.phone, -- 业主手机号
d.real_name zgy_name, -- 所属专管员
count(distinct case
when c.str_day <= '20160821' then
c.login_name
end) login_count,
count(distinct case
when c.str_day <= '20160821' then
decode(c.status, 1, c.invest_id, null)
end) user_count
from (select /*+ qb_name(sb) */ agent_id, city, username, real_name, phone
from agent.TB_AGENT_INFO
where agent_id in
(SELECT agent_id
FROM (SELECT distinct *
FROM TB_CHANNEL_INFO t
START WITH t.CHANNEL_ID in
(select CHANNEL_ID
from TB_USER_CHANNEL
where USER_ID = 596)
CONNECT BY PRIOR
t.CHANNEL_ID = t.PARENT_CHANNEL_ID)
WHERE agent_id IS NOT NULL)) a
left join oss_user_station e
on a.agent_id = e.agent_id
and e.user_type = 0
left join tb_user_zgy d
on e.username = d.username
left join (select * from act.tb_user_agent_relat c) c
on a.agent_id = c.agent_id
group by a.city,
a.username,
a.real_name,
a.phone,
d.real_name,
a.agent_id) a
left join (select invest_id, order_amount, agent_id, str_day
from agent.base_data_invest_info
where str_day >= '20150801' and str_day<='20160821') b
on a.agent_id = b.agent_id
group by a.city,
a.agent_id,
a.username,
a.real_name,
a.phone,
a.zgy_name,
a.login_count,
a.user_count

至此sql从一个小时都跑不完,到最后两秒跑完,工作已经完成,但是单从慢的执行计划中并没有看出什么问题。有聚合函数group by走hash没有错,虽然有全表扫描带*但是要么过滤性太差,要么不是性能瓶颈。那为什么总共300多w就跑不完了呢
慢的执行计划做一个10046
Number of plan statistics captured: 1
Rows (1st) Rows (avg) Rows (max) Row Source Operation
---------- ---------- ---------- ---------------------------------------------------
0 0 0 HASH GROUP BY (cr=0 pr=0 pw=0 time=278 us cost=3934270 size=6937507584 card=55059584)
0 0 0 VIEW VW_DAG_1 (cr=0 pr=0 pw=0 time=111 us cost=3934270 size=6937507584 card=55059584)
0 0 0 HASH GROUP BY (cr=0 pr=0 pw=0 time=108 us cost=3934270 size=6607150080 card=55059584)
0 0 0 VIEW VM_NWVW_0 (cr=0 pr=0 pw=0 time=32 us cost=2456206 size=6607150080 card=55059584)
0 0 0 SORT GROUP BY (cr=0 pr=0 pw=0 time=31 us cost=2456206 size=11177095552 card=55059584)
148234852 148234852 148234852 HASH JOIN RIGHT OUTER (cr=34882 pr=0 pw=0 time=34098445 us cost=21643 size=11177095552 card=55059584)
29651 29651 29651 TABLE ACCESS FULL TB_USER_AGENT_RELAT (cr=332 pr=0 pw=0 time=8201 us cost=102 size=1229228 card=27937)
703556 703556 703556 HASH JOIN OUTER (cr=34550 pr=0 pw=0 time=1518631 us cost=21392 size=536480628 card=3374092)
612 612 612 HASH JOIN SEMI (cr=272 pr=0 pw=0 time=31359 us cost=2007 size=193456 card=1712)
1751 1751 1751 HASH JOIN RIGHT OUTER (cr=100 pr=0 pw=0 time=11404 us cost=32 size=178048 card=1712)
43 43 43 TABLE ACCESS FULL TB_USER_ZGY (cr=2 pr=0 pw=0 time=103 us cost=3 size=903 card=43)
1751 1751 1751 HASH JOIN RIGHT OUTER (cr=98 pr=0 pw=0 time=6664 us cost=29 size=142096 card=1712)
1312 1312 1312 TABLE ACCESS FULL OSS_USER_STATION (cr=15 pr=0 pw=0 time=420 us cost=6 size=25800 card=1075)
1751 1751 1751 TABLE ACCESS FULL TB_AGENT_INFO (cr=83 pr=0 pw=0 time=1804 us cost=23 size=101008 card=1712)
612 612 612 VIEW VW_NSO_1 (cr=172 pr=0 pw=0 time=19720 us cost=1975 size=146439 card=16271)
612 612 612 VIEW (cr=172 pr=0 pw=0 time=19351 us cost=1975 size=146439 card=16271)
613 613 613 HASH UNIQUE (cr=172 pr=0 pw=0 time=19224 us cost=1975 size=9095489 card=16271)
1215 1215 1215 CONNECT BY WITHOUT FILTERING (UNIQUE) (cr=172 pr=0 pw=0 time=16687 us)
603 603 603 HASH JOIN RIGHT SEMI (cr=97 pr=0 pw=0 time=4922 us cost=29 size=149990 card=530)
603 603 603 TABLE ACCESS FULL TB_USER_CHANNEL (cr=22 pr=0 pw=0 time=550 us cost=7 size=7800 card=600)
1807 1807 1807 TABLE ACCESS FULL TB_CHANNEL_INFO (cr=75 pr=0 pw=0 time=1615 us cost=22 size=487890 card=1807)
1807 1807 1807 TABLE ACCESS FULL TB_CHANNEL_INFO (cr=75 pr=0 pw=0 time=1133 us cost=22 size=487890 card=1807)
1631878 1631878 1631878 TABLE ACCESS FULL BASE_DATA_INVEST_INFO (cr=34278 pr=0 pw=0 time=950767 us cost=19375 size=155208232 card=3374092)
id 6 1亿4千多万,一个多小时也没跑出来
并且temp撑爆了
第 43 行出现错误:
ORA-01652: 无法通过 128 (在表空间 TEMP 中) 扩展 temp 段
一亿四千多万,b表才300万,sql group by之前也不过一百多万的结果
根据 6 -
access("AGENT_ID"="C"."AGENT_ID"(+)) 查看c和b表agent_id数据分布
select agent_id,count(*) from act.tb_user_agent_relat group by agent_id order by 2 desc

最多的6827行,最少的1行
select agent_id,count(*) from agent.base_data_invest_info group by agent_id order by 2 desc

最多50w,最少1行
又一次进了hash join链接列数据分布不均匀的坑,hash join只适合数据分布均匀的列做链接条件
做个oradebug short_stack
SQL> select unique sid from v$mystat;
SID
----------
1132
SQL> select p.spid from v$process p ,v$session s where s.paddr=p.addr and s.sid=1132;
SPID
------------------------------------------------
28539
oradebug setospid 28539
SQL> oradebug short_stack
ksedsts()+465<-ksdxfstk()+32<-ksdxcb()+1927<-sspuser()+112<-__sighandler()<-io_submit()+7<-skgfqio()+1275<-ksfd_skgfqio()+894<-ksfdgo()+423<-ksfdaio()+2290<-kcflbi()+906<-kcbldio()+3104<-kcblsltio()+530<-stsIssueWrite()+118<-stsGetBlock()+442<-sdbinb()+135<-sdbput()+1042<-smbwrt()+247<-smbput()+2503<-sorput()+93<-qesaEvaAndPutDistAggOpns()+590<-qergsRowP()+430<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-qerhjGenProbeHashTable()+718<-kdstf11011010000km()+673<-kdsttgr()+153241<-qertbFetch()+2455<-rwsfcd()+103<-qerhjFetch()+1661<-rwsfcd()+103<-qerhjFetch()+1661<-qergsFetch()+757<-qervwFetch()+139<-qerghFetch()+315<-qervwFetch()+139<-qerghFetch()+315<-opifch2()+2766<-kpoal8()+2833<-opiodr()+917<-ttcpip()+2183<-opitsk()+1710<-opiino()+969<-opiodr()+917<-opidrv()+570<-sou2o()+103<-opimai_real()+133<-ssthrdmain()+265<-main()+201<-__libc_start_main()+244
SQL>
SQL>
SQL>
SQL>
SQL> oradebug short_stack
ksedsts()+465<-ksdxfstk()+32<-ksdxcb()+1927<-sspuser()+112<-__sighandler()<-io_submit()+7<-skgfqio()+1275<-ksfd_skgfqio()+894<-ksfdgo()+423<-ksfdaio()+2290<-kcflbi()+906<-kcbldio()+3104<-kcblsltio()+530<-stsIssueWrite()+118<-stsGetBlock()+442<-sdbinb()+135<-sdbput()+1042<-smbwrt()+247<-smbput()+2503<-sorput()+93<-qesaEvaAndPutDistAggOpns()+590<-qergsRowP()+430<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-kdstf11011010000km()+673<-kdsttgr()+153241<-qertbFetch()+2455<-rwsfcd()+103<-qerhjFetch()+1661<-rwsfcd()+103<-qerhjFetch()+1661<-qergsFetch()+757<-qervwFetch()+139<-qerghFetch()+315<-qervwFetch()+139<-qerghFetch()+315<-opifch2()+2766<-kpoal8()+2833<-opiodr()+917<-ttcpip()+2183<-opitsk()+1710<-opiino()+969<-opiodr()+917<-opidrv()+570<-sou2o()+103<-opimai_real()+133<-ssthrdmain()+265<-main()+201<-__libc_start_main()+244
SQL>
SQL>
SQL>
SQL>
SQL> oradebug short_stack
ksedsts()+465<-ksdxfstk()+32<-ksdxcb()+1927<-sspuser()+112<-__sighandler()<-qergsRowP()+2161<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-kdstf11011010000km()+673<-kdsttgr()+153241<-qertbFetch()+2455<-rwsfcd()+103<-qerhjFetch()+1661<-rwsfcd()+103<-qerhjFetch()+1661<-qergsFetch()+757<-qervwFetch()+139<-qerghFetch()+315<-qervwFetch()+139<-qerghFetch()+315<-opifch2()+2766<-kpoal8()+2833<-opiodr()+917<-ttcpip()+2183<-opitsk()+1710<-opiino()+969<-opiodr()+917<-opidrv()+570<-sou2o()+103<-opimai_real()+133<-ssthrdmain()+265<-main()+201<-__libc_start_main()+244
SQL> oradebug short_stack
ksedsts()+465<-ksdxfstk()+32<-ksdxcb()+1927<-sspuser()+112<-__sighandler()<-lmebco()+63<-qesaSimpleCompare()+73<-smbput()+913<-sorput()+93<-qergsRowP()+1067<-qerhjWalkHashBucket()+397<-qerhjGenProbeHashTable()+1571<-qerhjGenProbeHashTable()+718<-kdstf11011010000km()+673<-kdsttgr()+153241<-qertbFetch()+2455<-rwsfcd()+103<-qerhjFetch()+1661<-rwsfcd()+103<-qerhjFetch()+1661<-qergsFetch()+757<-qervwFetch()+139<-qerghFetch()+315<-qervwFetch()+139<-qerghFetch()+315<-opifch2()+2766<-kpoal8()+2833<-opiodr()+917<-ttcpip()+2183<-opitsk()+1710<-opiino()+969<-opiodr()+917<-opidrv()+570<-sou2o()+103<-opimai_real()+133<-ssthrdmain()+265<-main()+201<-__libc_start_main()+244
可以看到qerhjWalkHashBucket
qerhjWalkHashBucket就表示在做hash join的过程中需要遍历hash bucket中的数据,当链接列数据分布不均,某些值特别多时,遍历其hash bucket的成本也就非常高,如果pga放不下了,就会放到temp进行磁盘io,这就是性能瓶颈的原因,这个例子把30g的temp表空间都撑爆了,可见hash bucket有多大!
做个SQL MONITOR,也可以看出,瓶颈在id 6。如果做一个sql rpt也可以发现sql执行过程中的每妙逻辑读实际并不高,因为时间都花在了遍历hash bucket中

视图合并、hash join连接列数据分布不均匀引发的惨案的更多相关文章
- Sort merge join、Nested loops、Hash join(三种连接类型)
目前为止,典型的连接类型有3种: Sort merge join(SMJ排序-合并连接):首先生产driving table需要的数据,然后对这些数据按照连接操作关联列进行排序:然后生产probed ...
- 多表连接的三种方式详解 hash join、merge join、 nested loop
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...
- oracle Hash Join及三种连接方式
在Oracle中,确定连接操作类型是执行计划生成的重要方面.各种连接操作类型代表着不同的连接操作算法,不同的连接操作类型也适应于不同的数据量和数据分布情况. 无论是Nest Loop Join(嵌套循 ...
- 多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式. 之前打算在sqlplus中用执行计划的,但是格式看起来有点乱,就用Toad 做了3个截图. 从3张图里我们看到了几点 ...
- Nested Loops,Hash Join 和 Sort Merge Join. 三种不同连接的不同:
原文:https://blog.csdn.net/tianlesoftware/article/details/5826546 Nested Loops,Hash Join 和 Sort Merge ...
- Oracle 三种连接方式 NESTED LOOP HASH JOIN SORT MERGE JOIN
NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大( ...
- Hash Join是Oracle CBO时代经常出现的一种连接方式
Hash Join是Oracle CBO时代经常出现的一种连接方式,对海量数据处理时经常出现在执行计划里.本篇的上篇(http://space.itpub.net/17203031/viewspace ...
- [20180705]关于hash join 2.txt
[20180705]关于hash join 2.txt --//昨天优化sql语句,执行计划hash join right sna,加入一个约束设置XX字段not null,逻辑读从上万下降到50.- ...
- oracle 表连接 - hash join 哈希连接
一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...
随机推荐
- 史航416第11次作业&总结
作业1:冒泡排序 #include <stdio.h> ],int n); int main() { ],n,i; printf("输入一个整数n:"); scanf( ...
- java实现简单的验证码(待增强)
package com.xxx; import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.a ...
- 初学c# -- 学习笔记(五) winfrom无边框四周阴影
刚用到这个功能,网上扯淡的东西太多了,都是2边阴影,还什么窗口叠加.ps作图啥的,什么玩意.还是老外实在,google找的,无边框窗体,四边透明阴影. public partial class For ...
- Python--Argparse学习感悟
笔者在https://docs.python.org/2/howto/argparse.html#id1上,学习到了argparse的基本概念和使用规范,学习过后忍不住将自己的一些体会和大家分享一下. ...
- Tesseract API在VS 2013中的配置以及调用
[Tesseract]Tesseract API在VS 2013中的配置以及调用 时间:2016-05-31 20:35:19 阅读:127 评论:0 收藏:0 ...
- 附加数据库失败,sql2008,断电数据库日志受损
附加数据库失败,提示:无法在数据库 'DBNAME' (数据库 ID 为 7)的页 (1:210288) 上重做事务 ID (0:0) 的日志记录或者在重做数据库 'DBNAME' 的日志中记录的操作 ...
- .net学习笔记--使用抽象方法实现多态
在使用抽象方法实现多态之前,我们必须知道一些知识点: 1.抽象类不能被实例化: 2.抽象类可以包含非抽象成员,它们可以由其子类继承调用. 我们可以先创建一个Person的抽象类,代码如下: abstr ...
- 重启eclipse color theme失效的解决办法
For Eclipse Mars users: In the main menu bar, go to Window > Preferences In the preference tree o ...
- Linux下Java安装与配置
一.卸载系统自带的JDK 如果Linux已经自带OpenJdk,我们需要将它卸载掉,否则可以直接[安装JDK] 查看Linux自带的JDK是否已安装,输入如下命令查看JAVA版本信息. java -v ...
- POJ 2010 Moo University - Financial Aid treap
按第一关键字排序后枚举中位数,就变成了判断“左边前K小的和 + 这个中位数 + 右边前K小的和 <= F",其中维护前K小和可以用treap做到. #include <cstdi ...