スケーラブルデータベースサーバ HiRDB Version 8 コマンドリファレンス(Windows(R)用)
1表検索の場合に,TABLE SCANとなって性能が悪くないか確認してください。
ORの両辺に同じ条件を指定している場合には,同じ条件をORの外へ抜き出してください。
ORは更にIN述語に変換した方がよい場合があります。詳細については,「(2) 探索条件にORを指定した検索(その2)」を参照してください。
C1にインデクス定義 SELECT * FROM T1 WHERE (C1=10 AND C2=20) OR (C1=10 AND C2=30) ↓ SELECT * FROM T1 WHERE C1=10 AND (C2=20 OR C2=30)
SELECT * FROM T1, T2 WHERE (T1.C1=T2.C1 AND T1.C2=10) OR (T1.C1=T2.C1 AND T2.C2=20) ↓ SELECT * FROM T1, T2 WHERE T1.C1=T2.C1 AND (T1.C2=10 OR T2.C2=20)
探索条件に対して同一列に対する条件をORで指定している場合に,サーチ条件がない,又はサーチ条件が有効でなくインデクスのサーチ範囲が絞れずに性能が悪くないか確認してください。
HiRDBのバージョン06-02以降の場合,HiRDBのバージョンが06-01よりも前で単一列インデクスが定義されている場合,及びHiRDBのバージョンが06-01よりも前で複数列インデクスが定義されている場合とでベターユースが異なります。
SELECT * FROM T1 WHERE C1=10 OR C1=20 ↓ SELECT * FROM T1 WHERE C1 IN (10,20)
SELECT * FROM T1 WHERE C1=10 OR C1=20 ↓ SELECT * FROM T1 WHERE C1 IN (10,20)
SELECT * FROM T1 WHERE C1 IN (10,20) ↓ SELECT * FROM T1 WHERE C1=10 OR C1=20
HiRDBのバージョンが06-01よりも前の複数列インデクスの場合でも,次の二つの条件を共に満たすときには,IN述語を使用してください。
Join TypeがCROSS JOINとなっている場合,内部的に直積処理をしています。結合条件にOR演算子を指定している場合,ORの両辺を別々に指定した集合演算(UNION,又はUNION ALL)を用いた等価なSQLにすると,効率的に検索できる可能性があります。
結合条件がORで結ばれている場合は,ORの両辺を別々に指定した集合演算を使用します。
結合条件をOR演算子で結んでいる場合,結合する表の直積をしてから,直積結果に対して結合条件を評価します。
OR演算子を分離すると,ネストループジョイン,又はマージジョインをするので,結合時のデータの突き合わせ回数を削減できます。
さらに,ネストループジョインをすると,結合にインデクスを使用できるので,入出力回数を削減できます。
SELECT DISTINCT * FROM T1, T2 WHERE (T1.C1=T2.C1 OR T1.C2=T2.C2) AND T1.C3=10 ↓ SELECT * FROM T1, T2 WHERE T1.C1=T2.C1 AND T1.C3=10 UNION SELECT * FROM T1, T2 WHERE T1.C2=T2.C2 AND T1.C3=10
SELECT * FROM T1, T2 WHERE (T1.C1=T2.C1 OR T1.C2=T2.C2) AND T1.C3=10 ↓ SELECT * FROM T1, T2 WHERE T1.C1=T2.C1 AND T1.C3=10 UNION ALL SELECT * FROM T1, T2 WHERE T1.C2=T2.C2 AND (T1.C1<>T2.C1 OR T1.C1 IS NULL OR T2.C1 IS NULL) AND T1.C3=10
AND演算で同じ列の>=述語と<=述語を結んでいる場合,SQL最適化処理をする前にBETWEEN述語に変換します。この場合,WHERE句の先に指定した述語から順に,BETWEEN述語に変換していきます。
AND演算で同じ列の>=述語と<=述語を結んだ条件とBETWEEN述語は,HiRDBの内部では等価に扱われるため,どちらで指定しても同じになります。
>=述語と<=述語が範囲を形成しているかどうか確認してください。
SELECT * FROM T1 WHERE C1 BETWEEN 10 AND 20 SELECT * FROM T1 WHERE C1>=10 AND C1 <= 20
SELECT * FROM T1 WHERE C1<=50 AND C1>=20 AND C1<=30 ↓ SELECT * FROM T1 WHERE C1 BETWEEN 20 AND 50 AND C1<=30
冗長な述語がある場合,データベースアクセス時に不要な条件判定がされます。冗長な条件はできるだけ削除するようにしてください。
HiRDB/パラレルサーバで複数の列に対するGROUP BY検索をする場合は,重複の少ないGROUP化列をGROUP BY句の先に指定してください。ただし,SQL最適化オプションに1024を指定していない場合だけです。
HiRDB/パラレルサーバで複数のフロータブルサーバを使用してGROUP BY処理をする場合に,フロータブルサーバへデータを振り分けるためにGROUP BY句の先頭の列でハッシングしています。GROUP BY句の先頭の列に重複が少ない場合,各フロータブルサーバへ均等にハッシングできるので,並列処理の効果が上がります。
SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C1,C2
(C1の重複数)>(C2の重複数)の場合は次のように変更します。
↓ SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C2,C1
SQL最適化オプションに1024を指定している場合には,すべてのグループ化列を使用してハッシングするので,GROUP BYの順番を入れ替える必要はありません。ただし,「17.6.2(4) ORDER BY,GROUP BYを指定した検索に使用する表のインデクス定義」に該当する場合には,グループ化列を入れ替えないでください。
インデクス T1(C2, C1) SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C1,C2 ORDER BY C1,C2 ↓ SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C2,C1 ORDER BY C1,C2
SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C1,C2 ORDER BY C2,C1 ↓ SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C2,C1 ORDER BY C2,C1 SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C1,C2 ORDER BY C2 DESC ↓ SELECT C1,C2,SUM(C3) FROM T1 GROUP BY C2,C1 ORDER BY C2 DESC
GROUP BY句に対して,「17.6.2(4) ORDER BY,GROUP BYを指定した検索に使用する表のインデクス定義」に該当するインデクスを定義できる場合,そちらを優先してください。
All Rights Reserved. Copyright (C) 2006, 2016, Hitachi, Ltd.