プロが教える店舗&オフィスのセキュリティ対策術

処理速度改善に向けて、3つ質問があります。
解答は1つでも良いのでお願いします。

1.検索条件が複数ある場合、もっとも絞れる物から検索するのが早いのでしょうか?
  (Indexはその順番に伴い変更する事を前提)

  例:
where
X = 3 (1000件中10件に絞れる)
and Y = 4 (1000件中100件に絞れる)
and Z = 5 (1000件中900件に絞れる)

上記のように、より絞れる物から検索する。

2.文字列で検索する場合、以下は同じ結果でしょうか。そしてパターン2の方が早いでしょうか
  ・パターン1
  where X <> 'Z'
・パターン2
  where X > 'Z' and X < 'Z'

3.条件式にTO_CHARが入った場合、indexカラムの場合、遅くなるでしょうか?
  下記SQLを直すとした場合、どのように直せるでしょうか?

SELECT * from X,Y
where TO_CHAR(X.DATE,'YYYYMM') = Y.DATE2(+)

A 回答 (3件)

> 1.検索条件が複数ある場合、もっとも絞れる物から検索するのが早いのでしょうか?


記述の順序には関係ありません。どれか一項目に絞るなら「X」に索引を貼るのが有効です。

> 2.文字列で検索する場合、以下は同じ結果でしょうか。そしてパターン2の方が早いでしょうか
そもそも「X <> 'Z'」と「X > 'Z' and X < 'Z'」は同一条件ではありません。後者は常にFALSEです。

> 3.条件式にTO_CHARが入った場合、indexカラムの場合、遅くなるでしょうか?
一般的に関数を用いた項目については索引を使用しません。
しかし、
SELECT * from X,Y
where TO_CHAR(X.DATE,'YYYYMM') = Y.DATE2(+)
とは
SELECT * FROM X LEFT JOIN Y ON TO_CHAR(X.DATE,'YYYYMM') = Y.DATE2
の意味ですから、X側のレコードは索引の有無に限らず全件アクセスされます。
逆にYのDATE2に索引があれば高速化できる余地があります。

この回答への補足

2は 「where X > 'Z' or X < 'Z'」 の事です。

ご解答ありがとうございました。
他の皆様もご解答、ありがとうございました。

補足日時:2012/05/12 00:03
    • good
    • 0

1.


(X, Y, Z) で複合索引を張るのであれば、(X, Y, Z) でも、(Z, Y, X) でも変わらないでしょう。
単一列の索引の場合は X を使用するのが最も効率が良いです。
ヒント句を指定しても良いですが、統計情報をちゃんと取得しておけば、
X, Y, Z の各列に索引が張られていても X が使用されるはずです。

2.
以下の2つは同じです。

・パターン1
  where X <> 'Z'
・パターン2
  where X > 'Z' or X < 'Z'

3.
書きなおす必要はありません。

Xの結果セット(レコード数)がYと比べて小さい場合は、
Y.DATE2列に索引がない場合は張ることを検討してください。

外部結合でNL結合される場合は、(+)が付いていない方が駆動表、
付いている方が内部表になります。
    • good
    • 0

1.


where X = 3 and Y = 4 and Z = 5 

where Z = 5 and Y = 4 and X = 3
も同じはずです。
(データベースの内部的なことなのではっきりとはいいませんが、内部的には同じ処理をしていないと
 SQLを解析して実際の処理をするところがおかしいとしか思えない。
 ・・・Oracle6とか7.0とか古過ぎるversionは?なところもありますが。) 

一方、インデックスの作り方では、上のどちらのwhere句でも
Z,Y,Xでインデックスを作るより、
X,Y,Zでインデックスを作ったほうが早いはず。
(但し、コストベースの場合はちゃんと統計情報を取っていないと、X = 3 (1000件中10件に絞れる)というのを正しく認識できないこともあります・・・きちんと統計情報を取っていれば問題ないということですが。)

2.
・パターン2
  where X > 'Z' and X < 'Z'

  where X > 'Z' or X < 'Z'
なら同じでしょう。処理速度もたぶん一緒。

3.
条件式にTO_CHARが入った場合、indexカラムの場合、遅くなるでしょうか?
⇒インデックスを使わなくなります。
TO_CHARが入ったfunctionインデックスを作っておけば、それを使うので、早く処理してくれますが。

SELECT * from X,Y
where TO_CHAR(X.DATE,'YYYYMM') = Y.DATE2(+)
については、ANo1の方が書いておられるように、Xはインデックスを使っていないので
関数を含んでいようがいまいが、一緒。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!