利用分析函数减少对表访问次数
Posted robinson1988
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用分析函数减少对表访问次数相关的知识,希望对你有一定的参考价值。
最近在给一银行客户优化数据仓库,发现了很多烂SQL
下面这条SQL有很好的教学作用,现拿来与大家分享
SQL语句如下:
select /*+ parallel(16) */ count(*)
from (SELECT HM,
DZ,
YB,
ZZDH,
ZJLX,
ZJHM,
JGBM,
ZH,
ZHLX,
KHRQ,
YXRQ,
SFLB,
FZJG,
XXLX
FROM SWP.GRKXHBS_XHX_KH
WHERE BSH IN
(SELECT BSH
FROM (SELECT
T.BSH, T.DZ, T.YB, T.ZZDH
FROM SWP.GRKXHBS_XHX_KH T
WHERE T.BSH IN (SELECT T.BSH
FROM SWP.GRKXHBS_XHX_KH T
WHERE NOT EXISTS
(SELECT
*
from swp.grkxhbs_bsh_tmp TMP
WHERE TMP.INTERNAL_KEY = T.BSH)
GROUP BY T.BSH
HAVING COUNT(*) > 1)
AND T.EDATE = '99991231'
MINUS
SELECT
T.BSH, T.DZ, T.YB, T.ZZDH
FROM SWP.GRKXHBS_XHX_KH T
WHERE T.BSH IN (SELECT T.BSH
FROM SWP.GRKXHBS_XHX_KH T
WHERE NOT EXISTS
(SELECT
*
from swp.grkxhbs_bsh_tmp TMP
WHERE TMP.INTERNAL_KEY = T.BSH)
GROUP BY T.BSH
HAVING COUNT(*) > 1)
AND EDATE <> '99991231'))
AND EDATE = '99991231'
AND DATA_DATE BETWEEN replace('2021-08-23', '-', '') AND
replace('2021-08-24', '-', '')) tcounttable;
Elapsed: 00:00:08.32
执行计划太乱了,不好格式化,就不贴了
Statistics
----------------------------------------------------------
924 recursive calls
2 db block gets
1206911 consistent gets
304135 physical reads
7214236 redo size
527 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
46 sorts (memory)
0 sorts (disk)
1 rows processed
SQL对GRKXHBS_XHX_KH表访问了5次,可以利用分析函数对上面SQL进行改写,让表只扫描一次,改写之后的SQL如下:
SELECT /*+ parallel(16) */
COUNT(*)
FROM (SELECT T.*, MIN(MARK) OVER(PARTITION BY BSH, DZ, YB, ZZDH) EDATE_STATUS
FROM (SELECT T.*,
CASE
WHEN EDATE = '99991231' THEN 1
WHEN EDATE IS NULL THEN NULL
ELSE
0
END MARK
FROM (SELECT T.*, COUNT(BSH) OVER(PARTITION BY BSH) CNT
FROM SWP.GRKXHBS_XHX_KH T
WHERE NOT EXISTS
(SELECT *
from swp.grkxhbs_bsh_tmp TMP
WHERE TMP.INTERNAL_KEY = T.BSH)) T
WHERE CNT > 1) T
) T
WHERE EDATE_STATUS = 1
and EDATE = '99991231'
AND DATA_DATE BETWEEN replace('2021-08-23', '-', '') AND
replace('2021-08-24', '-', '');
Elapsed: 00:00:03.10
Statistics
----------------------------------------------------------
96 recursive calls
0 db block gets
294767 consistent gets
0 physical reads
0 redo size
527 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
32 sorts (memory)
0 sorts (disk)
1 rows processed
SQL改写之后,逻辑读由之前的1206911降低到294767,提升了近5倍性能
这个数据仓库里面有大量的存储过程(6000个)和大量的烂SQL(几千个),要忙死了,脑壳痛
以上是关于利用分析函数减少对表访问次数的主要内容,如果未能解决你的问题,请参考以下文章