[Seasar-user:20268] Re: [DBFlute]OracleでDATE型カラムのインデックスが利用されない

kubo [E-MAIL ADDRESS DELETED]
2010年 10月 21日 (木) 20:52:00 JST


久保(jflute)です。

小林さん、フォローありがとうございます。

> java.sql.Date      -> Oracle の DATE 型扱い
> java.sql.Timestamp -> Oracle の TIMESTAMP 型扱い
>
> ということで、java.sql.Timestamp を使うと
> DATE のカラムと TIMESTAMP のバインド変数の比較となり、
> それは DATE を TIMESTAMP に変換して行われるので、
> インデックスがうまく使われなかったりするのでは
> ないかなぁと思ったり。

なるほど、そもそもDBMSに依存しないJDBCの型の中で、
Oracle の DATE 型をぴったし当てはめられる型が存在しない
というところですかね。
そして、java.sql.Date が一応扱い的には当てはまっても、
java.sql.Date 自体は時分秒のない日付なので、
実際に使うと、検索条件の日付の時分秒が切り取られたり、
データ取得するときに時分秒が切り取られたりと。

DATE型カラムのメタデータが:
  ojdbc5.jar = java.sql.Types.DATE
  ojdbc6.jar = java.sql.Types.TIMESTAMP
となっていたので TIMESTAMP の指定で問題ないかなと
思ったのですが、(実際検索の動きとしては問題ないですが)
内部的には型違いと。

>> 検索条件に設定された java.util.Date が時分秒を
>> 持っていない場合に限り setDate() の方を利用する
>>
>> っていう処理を入れるとフィットするのかもですね。
>
> しゃってんさんの場合はたまたま DATE 型のカラムが
> 日付のみなのでそれでもよさげですが、日付と時刻を
> 持つ DATE 型のカラムの場合に遅くなるのは
> 避けられないように思います。

データ取得は getTimestamp() を使って、検索条件のバインド
するときだけ、設定された日付が時分秒がなければ setDate()
を使うようにすれば:

o DATE 型のカラムで実質時分秒がない + 検索条件も時分秒なし
o DATE 型のカラムで実質時分秒があり + 検索条件は時分秒なし

という状況に限り、インデックスの利用効率を上げることが
できるのかなと思います。(かつ、他の状況には影響せずに)
発生した現象から考えて理論上という感じですが。
(検証しづらい課題はつらいですね...)
ただ、結局以下のときの考慮ができないので中途半端かもですね。

o DATE 型のカラムで実質時分秒があり + 検索条件も時分秒あり

> Oracle JDBC ドライバには oracle.sql.DATE という
> 型があるので、java.sql.Timestamp からこの型に
> 変換して、OraclePreparedStatement#setDATE() に
> 渡すなんてのが Oracle 的に好ましいやり方なのかも。

O/Rマッパには厳しい話ですね。。。
いっそリフレクションでガツンってのは
やはり無理矢理過ぎるかなぁ。

2010/10/21 Koichi Kobayashi <[E-MAIL ADDRESS DELETED]>:
> 小林 (koichik) です.
>
> Date: Thu, 21 Oct 2010 18:29:47 +0900
> From: kubo <[E-MAIL ADDRESS DELETED]>
> Subject: [Seasar-user:20265] Re: [DBFlute]OracleでDATE型カラムのインデックスが利用されない
>
>> java.sql.Date を利用することで、ある意味、
>> 「時分秒は考慮しなくていいよ」っていうヒントに
>> なって、速くなるんですね。
>
> そっちですかねぇ?
>
> java.sql.Date      -> Oracle の DATE 型扱い
> java.sql.Timestamp -> Oracle の TIMESTAMP 型扱い
>
> ということで、java.sql.Timestamp を使うと
> DATE のカラムと TIMESTAMP のバインド変数の比較となり、
> それは DATE を TIMESTAMP に変換して行われるので、
> インデックスがうまく使われなかったりするのでは
> ないかなぁと思ったり。
>
> もしそうだとすると、
>
>> 検索条件に設定された java.util.Date が時分秒を
>> 持っていない場合に限り setDate() の方を利用する
>>
>> っていう処理を入れるとフィットするのかもですね。
>
> しゃってんさんの場合はたまたま DATE 型のカラムが
> 日付のみなのでそれでもよさげですが、日付と時刻を
> 持つ DATE 型のカラムの場合に遅くなるのは
> 避けられないように思います。
>
> Oracle JDBC ドライバには oracle.sql.DATE という
> 型があるので、java.sql.Timestamp からこの型に
> 変換して、OraclePreparedStatement#setDATE() に
> 渡すなんてのが Oracle 的に好ましいやり方なのかも。
>
>
> しゃってんさん:
>
> 以下のケースも試してみてください。
>
> import oracle.sql.DATE;
> import oracle.jdbc.OraclePreparedStatement;
>
> java.util.Date date = ...;
> PreparedStatement ps = ...;
>
> ((OraclePreparedStatement) ps).setDATE(index, new DATE(date));
> ...
>
>
>
> --
> <component name="koichik">
>    <property name="fullName">"Koichi Kobayashi"</property>
>    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
>    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
>    <property name="twitter">"http://twitter.com/koichik"</property>
> </component>
>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>


Seasar-user メーリングリストの案内