- ある作業の性能を改善する最高の方法はその作業自体をしないということだ。
本当に名言の中の名言です。
次に簡単な例があります。
1. これ以上チューニング不可能に見える完璧に最適化された文章です。ほぼ3.4秒がかかりました。
TPACK@ukja1106> declare
2 v_value number;
3 begin
4 for idx in 1 .. 100000 loop
5 select trunc(idx) into v_value from dual;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.42
本当にそうでしょうか。上で話した絶対原則を適用したら?不必要なSELECT ... FROM DUAL分をなくしたら?
TPACK@ukja1106> declare
2 v_value number;
3 begin
4 for idx in 1 .. 100000 loop
5 v_value := trunc(idx);
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.07
0.07秒だけで作業が終わります。
2. DECODE関数はSQL文章内のみで修行可能です。従ってCASE...文に変換すれば同じ効果を享受できます。
TPACK@ukja1106> -- decode
TPACK@ukja1106> declare
2 v_value varchar2(1);
3 begin
4 for idx in 1 .. 100000 loop
5 select decode(mod(idx,2),0,'A','B') into v_value from dual;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.59
TPACK@ukja1106> -- case
TPACK@ukja1106> declare
2 v_value varchar2(1);
3 begin
4 for idx in 1 .. 100000 loop
5 v_value := case mod(idx,2) when 0 then 'A' else 'B' end;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.15
3. Oracle 11gからはSequenceの値もSELECT ... FROM DUALを通じなくて直接えることがでいます。でも性能に与える影響はほとんどありませんね。
TPACK@ukja1106> -- SELECT... FROM DUAL
TPACK@ukja1106> declare
2 v_value number;
3 begin
4 for idx in 1 .. 100000 loop
5 select s1.nextval into v_value from dual;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.73
TPACK@ukja1106> -- 直接
TPACK@ukja1106> declare
2 v_value number;
3 begin
4 for idx in 1 .. 100000 loop
5 v_value := s1.nextval;
6 end loop;
7 end;
8 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.64
うん。。。なぜでしょうか。それに対する応えはSQL*Traceを通じて得られます。SQL*Traceを実行してみたら{ v_value := s1.nextval }作業は{ Select S1.NEXTVAL from dual }
もう一度言いますが、性能改善の一番の原則は!
- ある作業の性能を改善する最高の方法はその作業自体をしないということだ。
No comments:
Post a Comment