[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2006/02/08(Wed) 09:23
投稿者名:ごろう
Eメール:
URL :
タイトル:
ORACLEで高速抽出
オラクル(7)でSelect分を使ってデータを抽出する際、
例えば、列SCODE(index付)に商品コードが入っていたとして最初が001のデータだけ抽出する場合。
substr(SCODE,1,2) = '001'
とするより、
SCODE like '001%'
とした方がインデックスが解除されないので高速と聞いています。
では、これが日付の場合はどうなのでしょうか?
例えば列UPDATE(index付)に'yyyy/mm/dd'で入っているデータを月だけで抽出する場合。
TO_CHAR(UPDATE,'yyyy/mm') = '2006/02'

UPDATE >= '2006/02/01' AND UPDATE <= '2006/02/28'
とはどちらが高速で処理できるのでしょうか?
TO_CHARを使うとやはりindexは解除されるのでしょうか?(時間入りの場合も同様)
よろしくお願いします。

投稿時間:2006/02/08(Wed) 12:25
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: ORACLEで高速抽出
> TO_CHAR(UPDATE,'yyyy/mm') = '2006/02'
> と
> UPDATE >= '2006/02/01' AND UPDATE <= '2006/02/28'
> とはどちらが高速で処理できるのでしょうか?

聞くまでも無く自分で計測して見れば解る事ではないでしょうか?

> 例えば、列SCODE(index付)に商品コードが入っていたとして最初が001のデータだけ抽出する場合。
> substr(SCODE,1,2) = '001'
> とするより、
> SCODE like '001%'
> とした方がインデックスが解除されないので高速と聞いています。
上記も実際に自分で試して見ないとどの位早くなるのか解らないでしょう。
条件や状況・環境等によっても変わってくるでしょうし。

私は、繰り返し処理する場合や処理速度が要求される場合は必ず、処理前後の
計測を行い処理時間を調べるようにしております。
そうする事によってどうすれば早く処理できるといった事も自然と身に付くし
結果として無駄が省けたコードが書けます。
hhttp://www.bcap.co.jp/hanafusa/VBHLP/sonota_no1.htm

投稿時間:2006/02/08(Wed) 13:48
投稿者名:ごろう
Eメール:
URL :
タイトル:
Re^2: ORACLEで高速抽出

> 聞くまでも無く自分で計測して見れば解る事ではないでしょうか?
本にLeftとLikeの事が載っていたので、to_charも同じなのかなぁ?って思って試してみました。
両方のパターンを何度か試して平均時間を出してみたのですが、
時間に大きな差が見られませんでした。
実際、結果はデータ量にもよるでしょうし、サーバは常に使用状態にあり正確な時間が取れいないのは
確かです。
ですので実際の所はどうなのか、もしご存知の方がいらっしゃればと思い質問してみました。
ダラダラ長くなっても読み辛いと思い、できるだけ短く質問をしようとしたのがマズかったようです
ね。
ありがとうございました。

投稿時間:2006/02/08(Wed) 15:09
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: ORACLEで高速抽出
> 時間に大きな差が見られませんでした。
同じSQLを繰り返し投げると、SQL の解析にかかる時間が省略されますし、
メモリが充分にある場合や、データ件数が少ない場合には、データ自体が
キャッシュされたりするので、時間計測では結果が曖昧になりますよ。


Oracle でも JET でも SQL でもそうですが、インデックスが適切に
使われているかを確認したいのであれば、SQL 実行計画ログを見た方が
よいでしょう。Oracle なら、PLAN_TABLE ですね。

そうすれば、インデックススキャンされているのか、フルスキャンなのかを
把握できますよね。

投稿時間:2006/02/08(Wed) 15:02
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: ORACLEで高速抽出
# この手の質問は、VB 系の掲示板ではなく、Oracle 系の掲示板に投げた方が良いかと。

> substr(SCODE,1,2) = '001'
これ、絶対に成り立たないような……?

> TO_CHAR(UPDATE,'yyyy/mm') = '2006/02'
この問い合わせだと、テーブル上の全件(のUPDATE列)に対して
変換関数を実行しなければならないので、効率が悪くなります。

> UPDATE >= '2006/02/01' AND UPDATE <= '2006/02/28'
これなら、(UPDATE列にインデックスが張られていれば)効率が良いでしょうが、
2006年2月のデータを探すのであれば、時刻部の有無に関わらず、

UPDATE >= TO_DATE('20060201', 'YYYYMMDD') AND
UPDATE <  TO_DATE('20060301', 'YYYYMMDD')

などとした方が安全かも。