先に検索するかが変わります。外への参照ありは外側問合せを先に、外への参照なしは副問合せを 先に検索します。そのため、絞り込める問合せを先に検索するように、外への参照あり/なしを考え る必要があります。外への参照ありで記述する場合は、EXISTS述語の副問合せを使用してください。
外への参照なしで記述する場合は、IN述語の副問合せを使用してください。
例を図 3-4-1に示します。
Point
副問合せ内を絞り込める場合は、外への参照なしIN 副問合せを使用する副問合せより外側問合せが絞り込める場合は、外への参照あり
EXISTS
を使用する○ SELECT ZA.SNAME FROM ZAIKO ZA
WHERE ZA.DNO IN (
SELECT DE.DNO FROM JUTYU DE WHERE DE.TCODE = 'A') ;
○ SELECT ZA.SNAME FROM ZAIKO ZA WHERE EXISTS (
SELECT * FROM JUTYU DE WHERE DE.DNO = ZA.DNO) AND ZA.SNAME = 'A' ;
外への参照無し
IN
の場合は、ZA.DNO
に インデクスを定義して、副問合せから外側 問合せへ突き合わせる。図 3-4-1 外への参照なし
IN
と、外への参照ありEXISTS
の使い分け副問合せ内が絞り込める場合は、
外への参照なし
IN
にて、副問合せを 先に検索したほうが良い。外側問合せが絞り込める場合は、
外への参照ありEXISTSにて、外側 問合せを先に検索したほうが良い。
DE.DNOにインデクスを定義して、外側
問合せから副問合せへ突き合わせる。副問合せに関する記述
3-4 -1 IN 副問合せと EXISTS の使い分け(解説)
外への参照無し
IN
副問合せ解説 外への参照有無により、先に検索する表が変わります。絞り込める表から検索で きるように、外への参照有無を使い分けます。
SELECT ZA.SNAME FROM ZAIKO ZA
WHERE ZA.DNO IN ( SELECT DE.DNO FROM JUTYU DE
WHERE DE.TCODE = 'A' ) ;
SELECT ZA.SNAME FROM ZAIKO ZA WHERE EXISTS ( SELECT *
FROM JUTYU DE
WHERE DE.DNO = ZA.DNO) AND ZA.SNAME = 'A' ;
ZAIKO JUTYU
TCODE DNO
作業表
TCODE='A'
①副問合せ検索
②外側問合せ検索
ZAIKO JUTYU
DNO SNAME
SNAME='A'
②副問合せ検索
①外側問合せ検索
外への参照あり
EXISTS
副問合せ副問合せに関する記述
© Hitachi, Ltd. 2013 , 2015. All rights reserved.
3-5 IN 副問合せと=副問合せの使い分け
41
Point
副問合せ内で1件しかヒットしない場合は、=副問合せを使用する
○
SELECT ZA.SNAME FROM ZAIKO ZA WHERE ZA.DNO = (SELECT DE.DNO FROM JUTYU DE WHERE DE.TCODE = 'A' ) ;
×
SELECT ZA.SNAME FROM ZAIKO ZAWHERE ZA.DNO IN (
SELECT DE.DNO FROM JUTYU DE WHERE DE.TCODE = 'A' ) ;
副問合せが1件しかヒットしないときは、
INを使用せず=を使用する。
図 3-5-1 IN副問合せと=副問合せの使い分け
主キーであるので、1件 しかヒットしない。
ZA.DNO
にインデクスを定義して、副問 合せから外側問合せへ突き合わせる。JUTYU表の主キー:JUTYU(TCODE)
主キーを探索条件の=条件で指定する場合など、副問合せ結果が1件であることが自 明な場合は、
IN
副問合せ(=ANY
副問合せも同様)
を使用せず=副問合せを使用してくだ さい。=副問合せであれば、作業表の作成が不要なこととインデクスが自由に使用できる ことから、高速化できます。例を図 3-5-1に示します。副問合せに関する記述
3-5 -1 IN 副問合せと=副問合せの使い分け(例)
図 3-5-2 IN副問合せと=副問合せの使い分け例
○
CREATE VIEW VIEW1 AS SELECT * FROM TBL1WHERE CCODE2 = (SELECT CCODE2 FROM TBL2
WHERE CNAME = 'NAME1') ;
×
CREATE VIEW VIEW1 AS SELECT * FROM TBL1WHERE CCODE2 IN (SELECT CCODE2 FROM TBL2
WHERE CNAME = 'NAME1') ; SELECT T3.CID AS C1_
・・・・・・
FROM TBL3 T3
INNER JOIN VIEW1 T1
ON T3.CCODE1 = T1.CCODE1 WHERE
(
T3.CID = 'A01' ・・・・・
) ;
主キー
TBL3 TBL1
ネストループジョイン
TBL1(CCODE1, CCODE2) のインデクス
IN副問合せではネストループジョイン
と同時に評価できず、探索範囲が 広がる。
インデクスで大量データ がヒットし性能劣化
ビュー表定義を=副問合せに変更して、
インデクスでの絞り込みができるようにした。
副問合せに関する記述
1件しかヒットしな いので=でよい
主キー
© Hitachi, Ltd. 2013 , 2015. All rights reserved.