次のような、クエリを投げたら直ぐ結果が出るのか?
何分、何秒かかるか?
データベースにはARRAY SIZEというものがある。
SELECTクエリを投げたら、DBはARRAY SIZE分、テーブルからデータを取る。
レコードが正しい結果となるため。
これが、全体範囲処理。。
要は、全体範囲処理を避け、部分範囲処理にして
速くて正しいSQL組み方があるのだ。
*部分範囲処理を図る方法を考えて見よう!!!
Cartesian product 条件なしの結合
JOINというのは重い処理なのか? よく現場で聞こえるんだ。JOINはオソイって。
JOINには多様な方法がある。NESTED LOOP, SORT MERGEなど。。。
実行計画を確認することが重要。OPTIMIZERがどういう風にSQLを解決してくれるのかを最後まで目で確かめることが必要だ。私たちは問題を解く学生じゃない。問題を解くのはOPTIMIZERなのだ。
OPTIMIZERは高い、OPTIMIZERに仕事をさせてみよう!!
Cartesian productは条件のないjoin。
Cartesian productは統計性帳票などで強い力を発揮してくれる。
テーブル EMP
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 1980-12-17 800 20
7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30
7521 WARD SALESMAN 7698 1981-02-22 1250 500 30
7566 JONES MANAGER 7839 1981-04-02 2975 20
7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30
7698 BLAKE MANAGER 7839 1981-05-01 2850 30
7782 CLARK MANAGER 7839 1981-06-09 2450 10
7788 SCOTT ANALYST 7566 1987-04-19 3000 20
7839 KING PRESIDENT 1981-11-17 5000 10
7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30
7876 ADAMS CLERK 7788 1987-05-23 1100 20
7900 JAMES CLERK 7698 1981-12-03 950 30
7902 FORD ANALYST 7566 1981-12-03 3000 20
7934 MILLER CLERK 7782 1982-01-23 1300 10
テーブル DEPT
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
上記の二つのテーブルを利用して、次のような結果を出してくれるsqlを組んでみよう。。
部署名 SUM(MANAGER) SUM(SALESMAN) SUM(CLERK) SUM(EX) SUM(部署別計)
ACCOUNTING 2450 1300 5000 8750
RESEARCH 2975 1900 6000 10875
SALES 2850 5600 950 9400
総計 8275 5600 4150 11000 29025
この結果は全社員の部署別、ジョブ別の給料の総計表である。
ポイントは総計があるレコードを作り出すためのsql組み方なのだ。
こういう統計性帳票を作るため、帳票ツールを機能を利用したり、何度もSQLを実行させ、その結果を画面に表示したりするケースが多いと思うが。
一番、はやい処理は?? 私は一つのSQLを組むことが一番速いと考えている。その理由は沢山ある(知りたい??今度にしよう)。
SQL作成の鉄則。。。
*同じテーブルは一回のみ読む
*恥ずかしくないSQL作成する
*クライアント、サーバ環境を理解し、SQLを組む
*集合的な考え方、SQLは一般的なプログラムのように組まないこと
*などなど、沢山あるが。。。
正解>
SELECT DECODE(FLAG,'1',DNAME,'総計') 部署名, SUM(MANAGER),SUM(SALESMAN),SUM(CLERK),SUM(EX),SUM(部署別計) FROM
(SELECT DNAME, MANAGER,SALESMAN,CLERK,EX,部署別計 FROM
(SELECT DEPTNO,
SUM(DECODE(JOB,'MANAGER',SAL)) "MANAGER",
SUM(DECODE(JOB,'SALESMAN',SAL)) "SALESMAN",
SUM(DECODE(JOB,'CLERK',SAL)) "CLERK",
SUM(DECODE(JOB,'MANAGER',NULL,'SALESMAN',NULL,'CLERK', NULL, SAL)) "EX",
SUM(SAL) "部署別計"
FROM EMP
GROUP BY DEPTNO) A, DEPT B
WHERE A.DEPTNO = B.DEPTNO) A,
(SELECT '1' FLAG FROM DUAL
UNION ALL
SELECT '2' FROM DUAL) B
GROUP BY DECODE(FLAG,'1',DNAME,'総計')
ORDER BY DECODE(FLAG,'1',DNAME,'総計')