这是我写的sql
select m.*, n.bal, f.checkdate
from grade_dtl n,
(select t.sys_id, t.acc_input, t.sal_id, max(t.check_date) checkdate
from mng_dtl t
where t.txn_type in ('1', '2')
and t.status_flag = '3'
group by t.sys_id, t.acc_input, t.sal_id) f,
(select a.organ_id,
a.sal_id,
e.empname,
b.orgname,
a.acc,
a.acc_input,
a.acc_home,
a.acc_type,
c.svt_name,
a.sal_type,
sum(a.ave_bal),
a.sys_id,
d.v_sys_nm,
a.svt_no,
a.cust_name,
a.open_date
from grade_dtl a, organ b, pub_svt c, map_sys d, emp e
where a.sal_id = e.empid
and a.open_brh_id = b.orgcode
and a.svt_no = c.svt_no(+)
and a.sys_id = d.v_sys_id(+)
and a.txn_dt >= '201001'
and a.txn_dt <= '201004'
and a.organ_id in
(select org
from zzjgb o
where typeid = '2'
and (org = '111901' or parentorg = '111901'))
group by a.organ_id,
e.empname,
a.cust_name,
a.acc,
b.orgname,
a.acc_input,
a.acc_home,
c.svt_name,
a.acc_type,
a.sal_type,
d.v_sys_nm,
a.svt_no,
a.open_date,
a.sal_id,
a.sys_id) m
where m.acc = n.acc
and m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id
and n.txn_dt = '201004'
这是2张主要的表,数据量都很大
create table GRADE_DTL
(
TXN_DT CHAR(6),
SAL_ID CHAR(10),
ORGAN_ID CHAR(9),
SAL_TYPE CHAR(1),
SYS_ID CHAR(2),
SVT_NO CHAR(2),
ACC_INPUT CHAR(25),
ACC CHAR(19),
ACC_HOME CHAR(19),
OPEN_BRH_ID CHAR(9),
ACC_TYPE CHAR(1),
AVE_BAL NUMBER(12,2),
BAL NUMBER(12,2),
GRADE NUMBER(12,2),
CUST_NAME VARCHAR2(40),
OPEN_DATE CHAR(8)
)
create unique index GRADE_DTL_INDEX on GRADE_DTL (TXN_DT, SAL_ID, SYS_ID, ACC_INPUT)create table MNG_DTL
(
REC_ID NUMBER(8) not null,
TXN_DT CHAR(8),
TXN_TYPE CHAR(1),
SYS_ID CHAR(2),
SVT_NO CHAR(2),
ACC_INPUT CHAR(25),
ACC CHAR(19),
ACC_HOME CHAR(19),
CUST_NAME VARCHAR2(40),
OPEN_BRH_ID CHAR(9),
OPEN_DATE CHAR(8),
OPEN_CASH NUMBER(12,2),
SAL_ID CHAR(10),
SAL_NM CHAR(20),
ORGAN_ID CHAR(9),
OLD_SAL_ID CHAR(10),
OLD_SAL_NM CHAR(20),
OLD_ORGAN_ID CHAR(9),
ACT_ORGAN CHAR(9),
APPLY_OPR_ID CHAR(10),
APPLY_OPR_NM CHAR(20),
CHECK_DATE CHAR(8),
CHECK_OPR_ID CHAR(10),
CHECK_OPR_NM CHAR(20),
STATUS_FLAG CHAR(1),
FAIL_REASON VARCHAR2(100),
CHECK_TYPE CHAR(1)
)
create index MNG_DTL_ACC on MNG_DTL (ACC)
create unique index MNG_DTL_REC on MNG_DTL (REC_ID)
create index MNG_DTL_STA on MNG_DTL (STATUS_FLAG)
create index MNG_DTL_DT_TY_ORG on MNG_DTL (TXN_DT, TXN_TYPE, ACT_ORGAN)
上面2张表 数据量都很大,于是我那样写sql,查询速度很慢
要从grade_dtl表中取ave的某个时间段的合计值,还要从grade_dtl表中取出这个时间段最末时间点bal的值,这些是主要的数据。
然后还要从mng_dtl表中取出一个最大checkdate时间的值,并且要与上面grade_dtl取出的数据相关联。用了3个字段 m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id
求优化
select m.*, n.bal, f.checkdate
from grade_dtl n,
(select t.sys_id, t.acc_input, t.sal_id, max(t.check_date) checkdate
from mng_dtl t
where t.txn_type in ('1', '2')
and t.status_flag = '3'
group by t.sys_id, t.acc_input, t.sal_id) f,
(select a.organ_id,
a.sal_id,
e.empname,
b.orgname,
a.acc,
a.acc_input,
a.acc_home,
a.acc_type,
c.svt_name,
a.sal_type,
sum(a.ave_bal),
a.sys_id,
d.v_sys_nm,
a.svt_no,
a.cust_name,
a.open_date
from grade_dtl a, organ b, pub_svt c, map_sys d, emp e
where a.sal_id = e.empid
and a.open_brh_id = b.orgcode
and a.svt_no = c.svt_no(+)
and a.sys_id = d.v_sys_id(+)
and a.txn_dt >= '201001'
and a.txn_dt <= '201004'
and a.organ_id in
(select org
from zzjgb o
where typeid = '2'
and (org = '111901' or parentorg = '111901'))
group by a.organ_id,
e.empname,
a.cust_name,
a.acc,
b.orgname,
a.acc_input,
a.acc_home,
c.svt_name,
a.acc_type,
a.sal_type,
d.v_sys_nm,
a.svt_no,
a.open_date,
a.sal_id,
a.sys_id) m
where m.acc = n.acc
and m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id
and n.txn_dt = '201004'
这是2张主要的表,数据量都很大
create table GRADE_DTL
(
TXN_DT CHAR(6),
SAL_ID CHAR(10),
ORGAN_ID CHAR(9),
SAL_TYPE CHAR(1),
SYS_ID CHAR(2),
SVT_NO CHAR(2),
ACC_INPUT CHAR(25),
ACC CHAR(19),
ACC_HOME CHAR(19),
OPEN_BRH_ID CHAR(9),
ACC_TYPE CHAR(1),
AVE_BAL NUMBER(12,2),
BAL NUMBER(12,2),
GRADE NUMBER(12,2),
CUST_NAME VARCHAR2(40),
OPEN_DATE CHAR(8)
)
create unique index GRADE_DTL_INDEX on GRADE_DTL (TXN_DT, SAL_ID, SYS_ID, ACC_INPUT)create table MNG_DTL
(
REC_ID NUMBER(8) not null,
TXN_DT CHAR(8),
TXN_TYPE CHAR(1),
SYS_ID CHAR(2),
SVT_NO CHAR(2),
ACC_INPUT CHAR(25),
ACC CHAR(19),
ACC_HOME CHAR(19),
CUST_NAME VARCHAR2(40),
OPEN_BRH_ID CHAR(9),
OPEN_DATE CHAR(8),
OPEN_CASH NUMBER(12,2),
SAL_ID CHAR(10),
SAL_NM CHAR(20),
ORGAN_ID CHAR(9),
OLD_SAL_ID CHAR(10),
OLD_SAL_NM CHAR(20),
OLD_ORGAN_ID CHAR(9),
ACT_ORGAN CHAR(9),
APPLY_OPR_ID CHAR(10),
APPLY_OPR_NM CHAR(20),
CHECK_DATE CHAR(8),
CHECK_OPR_ID CHAR(10),
CHECK_OPR_NM CHAR(20),
STATUS_FLAG CHAR(1),
FAIL_REASON VARCHAR2(100),
CHECK_TYPE CHAR(1)
)
create index MNG_DTL_ACC on MNG_DTL (ACC)
create unique index MNG_DTL_REC on MNG_DTL (REC_ID)
create index MNG_DTL_STA on MNG_DTL (STATUS_FLAG)
create index MNG_DTL_DT_TY_ORG on MNG_DTL (TXN_DT, TXN_TYPE, ACT_ORGAN)
上面2张表 数据量都很大,于是我那样写sql,查询速度很慢
要从grade_dtl表中取ave的某个时间段的合计值,还要从grade_dtl表中取出这个时间段最末时间点bal的值,这些是主要的数据。
然后还要从mng_dtl表中取出一个最大checkdate时间的值,并且要与上面grade_dtl取出的数据相关联。用了3个字段 m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id
求优化
select m.*, n.bal, f.checkdate
from grade_dtl n,
(select t.sys_id, t.acc_input, t.sal_id, max(t.check_date) checkdate
from mng_dtl t
where (t.txn_type = '1' or t.txn_type='2') --in 改成 or
and t.status_flag = '3'
group by t.sys_id, t.acc_input, t.sal_id) f,
(select a.organ_id,
a.sal_id,
e.empname,
b.orgname,
a.acc,
a.acc_input,
a.acc_home,
a.acc_type,
c.svt_name,
a.sal_type,
sum(a.ave_bal),
a.sys_id,
d.v_sys_nm,
a.svt_no,
a.cust_name,
a.open_date
from grade_dtl a, organ b, pub_svt c, map_sys d, emp e
where a.sal_id = e.empid
and a.open_brh_id = b.orgcode
and a.svt_no = c.svt_no(+)
and a.sys_id = d.v_sys_id(+)
and a.txn_dt >= '201001'
and a.txn_dt <= '201004'
and exists( --in 改为exists
(select 1 from zzjgb o
where typeid = '2'
and (org = '111901' or parentorg = '111901')
and a.organ_id=org)
group by a.organ_id,
e.empname,
a.cust_name,
a.acc,
b.orgname,
a.acc_input,
a.acc_home,
c.svt_name,
a.acc_type,
a.sal_type,
d.v_sys_nm,
a.svt_no,
a.open_date,
a.sal_id,
a.sys_id) m
where m.acc = n.acc
and m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id
and n.txn_dt = '201004'
要合计一段时间内每个账号acc里的ave_bal的数额,
就是这样a.txn_dt >= '201001' and a.txn_dt <= '201004'这样取一个时间段的合计,我写的sql查询出的一个m表就是这里结果。
然后还要取这段时间末的时间点的一个bal的数额
又查询了一次GRADE_DTL表取n.txn_dt = '201004'这个时间点的bal值
然后从上面的结果中m.acc = n.acc取关联的数据。mng_dtl这个是一个人员sal_id与账号acc建立关系的审核信息表,因为mng_dtl里没有acc的属性,所以后来连接的时候用了3个属性相等
m.acc_input = f.acc_input
and m.sal_id = f.sal_id
and m.sys_id = f.sys_id (select t.sys_id, t.acc_input, t.sal_id, max(t.check_date) checkdate
from mng_dtl t
where t.txn_type in ('1', '2')
and t.status_flag = '3'
group by t.sys_id, t.acc_input, t.sal_id) f
f这个是为了,取一个sal_id与acc_input建立关系的审核日期,这个要取最后一天其他几个表基本就是参数表了
要查的主要结果就是
人员sal_id 账号acc 总数(sum(ave.bal)) 时间段末的数额(bal) 审核日子(checkdate)
12 rows selected.Elapsed: 00:00:21.80Execution Plan
----------------------------------------------------------
Plan hash value: 1762746607--------------------------------------------------------------------------------
-------------------------| Id | Operation | Name | Rows | Bytes |TempSpc
| Cost (%CPU)| Time |--------------------------------------------------------------------------------
-------------------------| 0 | SELECT STATEMENT | | 1380 | 526K|
| 57331 (1)| 00:13:23 ||* 1 | HASH JOIN | | 1380 | 526K|
| 57331 (1)| 00:13:23 || 2 | JOIN FILTER CREATE | :BF0000 | 1380 | 455K|
| 41693 (1)| 00:09:44 ||* 3 | HASH JOIN | | 1380 | 455K|
| 41693 (1)| 00:09:44 || 4 | VIEW | | 965 | 250K|
| 20936 (1)| 00:04:54 || 5 | HASH GROUP BY | | 965 | 231K|
| 20936 (1)| 00:04:54 ||* 6 | HASH JOIN | | 965 | 231K|
| 20935 (1)| 00:04:54 ||* 7 | HASH JOIN | | 965 | 220K|
| 20863 (1)| 00:04:53 || 8 | TABLE ACCESS FULL | ORGAN | 2040 | 53040 |
| 24 (0)| 00:00:01 ||* 9 | HASH JOIN RIGHT OUTER | | 965 | 196K|
| 20839 (1)| 00:04:52 || 10 | TABLE ACCESS FULL | PUB_SVT | 39 | 1716 |
| 22 (0)| 00:00:01 ||* 11 | HASH JOIN RIGHT OUTER| | 965 | 154K|
| 20816 (1)| 00:04:52 || 12 | TABLE ACCESS FULL | MAP_SYS | 2 | 34 |
| 22 (0)| 00:00:01 ||* 13 | HASH JOIN | | 965 | 138K|
| 20794 (1)| 00:04:52 || 14 | SORT UNIQUE | | 24 | 552 |
| 24 (0)| 00:00:01 ||* 15 | TABLE ACCESS FULL | ZZJGB | 24 | 552 |
| 24 (0)| 00:00:01 ||* 16 | TABLE ACCESS FULL | GRADE_DTL | 979K| 115M|
| 20764 (1)| 00:04:51 || 17 | TABLE ACCESS FULL | EMP | 17742 | 207K|
| 71 (0)| 00:00:01 ||* 18 | TABLE ACCESS FULL | GRADE_DTL | 979K| 67M|
| 20752 (1)| 00:04:51 || 19 | VIEW | | 1102K| 55M|
| 15632 (1)| 00:03:39 || 20 | HASH GROUP BY | | 1102K| 49M| 67M
| 15632 (1)| 00:03:39 || 21 | JOIN FILTER USE | :BF0000 | 1102K| 49M|
| 7515 (1)| 00:01:46 ||* 22 | TABLE ACCESS FULL | MNG_DTL | 1102K| 49M|
| 7515 (1)| 00:01:46 |--------------------------------------------------------------------------------
-------------------------
Predicate Information (identified by operation id):
--------------------------------------------------- 1 - access("N"."ACC_INPUT"="F"."ACC_INPUT" AND "N"."SAL_ID"="F"."SAL_ID" AND
"N"."SYS_ID"="F"."SYS_ID")
3 - access("M"."FILE4"="N"."ACC")
6 - access("E"."EMPID"=TO_NUMBER("A"."SAL_ID"))
7 - access("A"."OPEN_BRH_ID"="B"."ORGCODE")
9 - access("A"."SVT_NO"="C"."SVT_NO"(+))
11 - access("A"."SYS_ID"="D"."V_SYS_ID"(+))
13 - access("A"."ORGAN_ID"="ORGCODE")
15 - filter("TOPID"=2 AND ("PARENTORG"='111901' OR "ORG"='111901
')) 16 - filter("A"."TXN_DT"='201009')
18 - filter("N"."TXN_DT"='201009')
22 - filter("T"."STATUS_FLAG"='3' AND ("T"."TXN_TYPE"='1' OR "T"."TXN_TYPE"='2
') AND SYS_OP_BLOOM_FILTER(:BF0000,"T"."ACC_INPUT","T"."SAL_ID","T"."SYS_
ID"))解释计划
一般都是查询30秒以上
with tmp as ( select t.txn_dt,t.sal_id,t.organ_id,t.sal_type,t.sys_id,t.svt_no,t.acc_input,t.acc,t.acc_home,t.open_brh_id,t.acc_type,t.ave_bal,t.bal,t.grade,t.cust_name,t.open_date
from grade_dtl t
where t.txn_dt >= '201001'
and t.txn_dt <= '201004'
and t.organ_id in
(select orgcode
from zzjgb o
where topid = '2'
and (orgcode = '111901' or parentorg = '111901'))
)select m.*,
n.bal file15,
e.empname file2,
b.orgname file3,
c.svt_name file8,
d.v_sys_nm file11,
f.checkdate checkdate
from tmp n,
(select t.sys_id, t.acc_input, t.sal_id, max(t.check_date) checkdate
from mng_dtl t
where t.txn_type in ('1', '2')
and t.status_flag = '3'
group by t.sys_id, t.acc_input, t.sal_id) f,
(select a.organ_id file1,
a.sal_id salid,
a.open_brh_id,
a.acc file4,
a.acc_input file5,
a.acc_home file6,
a.acc_type file7,
a.sal_type file9,
round(nvl(sum(a.ave_bal), 0) / (4), 2) file10,
a.sys_id sysid,
a.svt_no file12,
a.cust_name file13,
a.open_date file14
from tmp a
group by a.organ_id,
a.cust_name,
a.acc,
a.open_brh_id,
a.acc_input,
a.acc_home,
a.acc_type,
a.sal_type,
a.svt_no,
a.open_date,
a.sal_id,
a.sys_id) m,
organ b,
pub_svt c,
map_sys d,
emp e
where m.file4 = n.acc
and n.acc_input = f.acc_input
and n.sal_id = f.sal_id
and n.sys_id = f.sys_id
and m.file4 = n.acc
and m.salid = e.empid
and m.open_brh_id = b.orgcode
and m.file12 = c.svt_no(+)
and m.sysid = d.v_sys_id(+)
and n.txn_dt = '201004'昨天改成这样查询,感觉有快了点
this kind of sql makes everyone be in hell
be careful