「Hard Parseに時間が掛かる手軽なSQLを作りたい。彡(゚)(゚)」と呟いた
(※下記twitterモーメント参照)ところ、色々とアイデアを頂いたので、
全部ではないのですがお試し&まとめてみましたやで彡(゚)(゚)
Hard Parseに時間が掛かるSQL ※twitterモーメント
https://twitter.com/i/moments/1001431132234072064
Case1. IN句リテラルを仕様上限(999個)まで
こちらの結果は下記の通り、ぼちぼち彡(゚)(゚)
SELECT A.ITEM_NAME
, COUNT(*)
FROM ITEM_TBL A
WHERE ITEM_NO IN (
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
:
975,976,977,978,979,980,981,982,983,984,985,986,987,988,989,990,991,992,993,994,995,996,997,998,999)
GROUP BY ITEM_NAME
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.08 0.09 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 2 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.08 0.09 0 2 0 10
Case2. 結合表8個以上
こちらの結果は下記の通り、Case1. よりは増えました彡(゚)(゚)
SELECT A.ITEM_NAME
, COUNT(*)
FROM ITEM_TBL A
, ITEM_TBL B
, ITEM_TBL C
, ITEM_TBL D
, ITEM_TBL E
, ITEM_TBL F
, ITEM_TBL G
, ITEM_TBL H
, ITEM_TBL I
, ITEM_TBL J
WHERE J.REGIST_DATE BETWEEN TO_DATE('2012/08/01', 'YYYY/MM/DD')
AND TO_DATE('2012/08/02', 'YYYY/MM/DD')
AND A.ITEM_NO = B.ITEM_NO
AND B.ITEM_NO = C.ITEM_NO
AND C.ITEM_NO = D.ITEM_NO
AND D.ITEM_NO = E.ITEM_NO
AND E.ITEM_NO = F.ITEM_NO
AND F.ITEM_NO = G.ITEM_NO
AND G.ITEM_NO = H.ITEM_NO
AND H.ITEM_NO = I.ITEM_NO
AND I.ITEM_NO = J.ITEM_NO
GROUP BY A.ITEM_NAME
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.48 0.48 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 10 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.48 0.48 0 10 0 10
Case3. 結合表8個以上 + permutation増強
こちらの結果は下記の通り、Case2. より更に増加彡(゚)(゚)
ALTER SESSION SET "_optimizer_max_permutations"=80000;
SELECT A.ITEM_NAME
, COUNT(*)
FROM ITEM_TBL A
, ITEM_TBL B
, ITEM_TBL C
, ITEM_TBL D
, ITEM_TBL E
, ITEM_TBL F
, ITEM_TBL G
, ITEM_TBL H
, ITEM_TBL I
, ITEM_TBL J
WHERE J.REGIST_DATE BETWEEN TO_DATE('2012/08/01', 'YYYY/MM/DD')
AND TO_DATE('2012/08/02', 'YYYY/MM/DD')
AND A.ITEM_NO = B.ITEM_NO
AND B.ITEM_NO = C.ITEM_NO
AND C.ITEM_NO = D.ITEM_NO
AND D.ITEM_NO = E.ITEM_NO
AND E.ITEM_NO = F.ITEM_NO
AND F.ITEM_NO = G.ITEM_NO
AND G.ITEM_NO = H.ITEM_NO
AND H.ITEM_NO = I.ITEM_NO
AND I.ITEM_NO = J.ITEM_NO
GROUP BY A.ITEM_NAME
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.66 0.68 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 10 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 0.67 0.69 0 10 0 10
Case4. UNION500行
こちらの結果は下記の通り、エエ感じやで!彡(^)(^)
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100 UNION
:
SELECT ITEM_NO FROM ITEM_TBL WHERE ITEM_NO BETWEEN 1 AND 100
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 1.04 1.05 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.01 0.01 0 500 0 10
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 1.06 1.06 0 500 0 10
Case5. DUAL表を200個結合
Kazumasa Obaraさんネタ。元ネタの500個だと
終わらなかったので200個で計測。ぶっちぎりで草wwwww
SELECT A.* FROM DUAL A,
DUAL,
:
DUAL,
DUAL,
DUAL,
DUAL,
DUAL
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 48.86 49.96 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 2 0.00 0.00 0 3 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 4 48.86 49.96 0 3 0 1
やっぱり結合順序の探索には時間が掛かるんやなぁ……彡(゚)(゚)
アイデアを頂いた皆さん、ありがとうございます!(`・ω・)ゞ