人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

OracleのEXISTS句で質問です。

EXISTSの後のSELECT文で

WHERE EXISTS (SELECT NULL ...
WHERE EXISTS (SELECT 'X' ...
WHERE EXISTS (SELECT 1 ...

のようにいろいろな書き方ができると思いますが、実際にどれが理想なのか説明しているサイトはありますか?

Oracleのディクショナリビューは「exists (select null・・・」としているものが多いようなんですが・・・
http://otn.oracle.co.jp/forum/thread.jspa?threadID=8008219&tstart=4227

●質問者: wasa
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:Oracle SELECT サイト 理想
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● chuken_kenkou
●27ポイント

標準SQLなどでは、

[NOT} EXISTS (SELECT * FROM ?)

という例が多いです。

しかし、EXISTS使用時、「SELECTの選択リストでは、選択式を1個しか指定できない」という原則を、厳密にチェックしているRDBMSもあり、「*」ではエラーになってしまう場合があります。そういったRDBMSでは、

[NOT} EXISTS (SELECT 1 FROM ?)

といった例題が使われている場合が多いです。


2 ● takerudayo
●27ポイント

的確に説明しているサイトは知りませんがここで考えを書いては駄目でしょうか。駄目ならポイント無しでいいです。


どれが理想との事ですが、いくつかの見方があるかと考えました。


できるだけSQLが早くなるのが理想だとすると、

「DBを高速化する一般的な考えは副問いも含めて全ての工程で出来る限り処理するデータ量を減らすこと」

だと考えられます。

そうなると質問に書かれているような記述方法の中から一番使用バイト数が少ない文字で行くのが

正しいと考えていいと思います。


次に早いSQLも欲しいけどSQLの見易さも理想だとすると、

http://www.shift-the-oracle.com/inside/in-exists-difference.html...

に書かれている通り、1とかの記述はよくないSQLと考えた方が良いと思います。


これらを踏まえると、

できるだけSQL処理が早くすみ、説明無くても意味が伝わる記述として、私は以下のような記述をお勧めします。


SELECT 出力カラム

FROM テーブル1

WHERE EXISTS (SELECT PKカラム or 評価条件部で使われるIndexと同等のカラム FROM テーブル2 WHERE 評価条件部)


この記述で目指しているのは、評価条件部で評価するのにDBがDBFから抽出したデータをそのままEXISTS内の出力カラムに使えば

DBとしては再度テーブル2からのデータ読み込み処理負荷がかからないという事で出来る限りの負荷減を目指している記述です。


参考になればと思います。


3 ● chuken_kenkou
●26ポイント

#1です。

#2回答者さんの意見に少し異議があるので、参考までに。

できるだけSQLが早くなるのが理想だとすると、

「DBを高速化する一般的な考えは副問いも含めて全ての工程で出来る限り処理するデータ量を減らすこと」

だと考えられます。

そうなると質問に書かれているような記述方法の中から一番使用バイト数が少ない文字で行くのが正しいと考えていいと思います。


次のような場合は、性能に大きく影響します。


SELECTの選択リストの値が1バイト小さくなる程度では、性能上はゴミのようなものです。

次に早いSQLも欲しいけどSQLの見易さも理想だとすると、

http://www.shift-the-oracle.com/inside/in-exists-difference.html...

に書かれている通り、1とかの記述はよくないSQLと考えた方が良いと思います。

「ちなみに、EXISTS の中の 副問い合わせには、'SELECT * FROM ?'を使用するより 'SELECT 1 FROM ?' などの固定項目を使用した方が早い(CBOでは過去形の可能性が大)。ただこれを知らない人がみると ???...何だこれ? になるので要注意なうえ、既に時代遅れの技に近いかもしれない。」

上記URLの記述は、

『「*」でなく「1」と記述した方が、過去には早いことがあったが、これを知らない人が見ると???になることがある。現在は「*」と書いても、オプティマイザが効率的に処理してくれる場合が多い』

といった意味で、「1」を指定するのはよくないとまでは言っていません。

SELECT 出力カラム

FROM テーブル1

WHERE EXISTS (SELECT PKカラム or 評価条件部で使われるIndexと同等のカラム FROM テーブル2 WHERE 評価条件部)

一番使用バイト数が少ない文字で行く


上記の二つは、「矛盾するのでは?」と思います。

国産RDBMSの開発に長年携わり、オプティマイザの内部処理についても一般の人よりは詳しい者からの意見です。参考まで。

◎質問者からの返答

どうもありがとうございます。確かに、

>「DBを高速化する一般的な考えは副問いも含めて全ての工程で出来る限り処理するデータ量を減らすこと」

という視点であれば、「1」という書き方がいいのでは?と感じました。

ただし、現在のRDBであれば、

>「*」と書いても、オプティマイザが効率的に処理してくれる場合が多い』

ということなら、「*」でもいいわけですね(通常私はOracle9.2を使っています、問題ないかと考えます)。

いろいろ参考になります、どうもありがとうございます。

ちなみに、もしご存知であれば

EXISTS (SELECT NULL ?

という記述には問題があるかどうか教えていただきたいです。

NULLであれば後工程の処理が減るのではないか?と少し思うのですが。。。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ