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

kubo [E-MAIL ADDRESS DELETED]
2010年 10月 21日 (木) 18:29:47 JST


久保(jflute)です。

しゃってんさん、素敵な報告ありがとうございます。
整理すると:

どっちにしてもインデックスは利用されるけど、
利用のされ方が違ってスピードに影響する

ってところですね。
java.sql.Date を利用することで、ある意味、
「時分秒は考慮しなくていいよ」っていうヒントに
なって、速くなるんですね。
他のDBでどうなのかは不明なので Oracle 限定で:

検索条件に設定された java.util.Date が時分秒を
持っていない場合に限り setDate() の方を利用する

っていう処理を入れるとフィットするのかもですね。
UtilDateAsTimestampType を継承して、
bindValue() の中で value が時分秒のない日付なら、
SqlDateType の bindValue() にディスパッチ。
良かったら試してみて下さい。DBFluteConfigの
メソッド経由で、ValueTypeは差し替えられるので。

DBFluteのデフォルト挙動にするかどうかは、
ちょっとこっち(Oracle10gXE)でも大量データの
環境を作って試してみて検討したいと思います。
(その環境を作るのが大変...)

2010/10/21  <[E-MAIL ADDRESS DELETED]>:
> しゃってんです。
>
>
> こちらの環境で簡単なテストを行ってみました。
>
> 1.DBFluteConfigを変更せず今まで通りでの検索を実行。
> 2.DBFluteConfigのUTILDATE_AS_TIMESTAMP を設定している箇所をコメントアウトして検索を実行。
> 3.PreparedStatementのsetDateを明示的に呼び出して検索を実行。
> 4.PreparedStatementのsetTimestampを明示的に呼び出して検索を実行。
> ※実行したSQLは、日付項目のFromToを条件にしたカウント文です。
>
> 結果は、
>  1 及び 4 は INDEX FAST FULL SCAN となり、
>  2 及び 3 は INDEX RANGE SCANとなりました。
>
>
> データ上の日付に時刻までを設定し、検索条件の日付にも検索結果が異なるように時刻を指定したjava.util.Dateから
> java.sql.Date 及び java.sql.Timestamp にそれぞれ変換して上記3及び4でのテスト行いました。
>
> 結果は、
>  setDate を呼び出した場合は時刻は考慮されずに日付のみで結果が取得できる。(このときは、INDEX RANGE SCAN)
>  setTimestamp を呼び出した場合は時刻まで考慮された検索結果が返却される。(ただし、INDEX FAST FULL SCAN )
>
>
> インデックスは利用されていましたが、利用のされ方が違いました。
>
> また、 1 及び 2 で条件を変えずにカウント文から一覧取得にした場合、
> 1 はTABLE ACCESS FULL での検索となり、
> 2 は INDEX RANGE SCAN となりました。
>
>
> kubo <[E-MAIL ADDRESS DELETED]>:
>> 久保(jflute)です。
>>
>>
>>
>> しゃってんさん、dbflute-oracle-example にて、
>>
>> JDBC直接利用で日付周りを検証するテスト書きました。
>>
>>
>>
>> VendorPlainTest.java
>>
>> test_PreparedStatement_bindDate_timeHandling_Tx()
>>
>>
>>
>> ※Oracle10g XE にて、ojdbc5.jar、ojdbc6.jarの両方でグリーン
>>
>>
>>
>> OracleのDATE型に対して、JDBCにおいて java.sql.Date で
>>
>> 取り扱うと、検索条件も値取得も時分秒が切り捨てられて
>>
>> しまうことが上記のテストでわかります。
>>
>> なので、DATE型に対しては、java.sql.Timestamp で取り扱う
>>
>> のが基本と考えられます。
>>
>>
>>
>> ただ、しゃってんさんの環境での現象が、
>>
>> 「java.sql.Date で設定すると逆にインデックスが利用される」
>>
>> ということになるのであれば、かなりややこしい問題となります。
>>
>>
>>
>> 状況確認の前に論理を整理してみましたが、
>>
>> 上記のようなややこしい問題なのか、それともまた別の要因があるのか、
>>
>> 確認するために以下のトライをお願いします。
>>
>>
>>
>> DBFluteConfigの処理をやめるとインデックスが利用されるか?
>>
>> ValueTypeは簡単に独自のものに差し替えられるので、
>>
>> JDBC に setDate() するか、setTimestamp() するかで、
>>
>> インデックスの利用有無の違いが発生しているのかどうかを
>>
>> 確認して頂けると幸いです。
>>
>>
>>
>> ※そもそも、Oracle11g だと上記のテスト結果が違うとか
>>
>>  だとさらにややこしくなりますが...
>>
>> _______________________________________________
>>
>> Seasar-user mailing list
>>
>> [E-MAIL ADDRESS DELETED]
>>
>> https://ml.seasar.org/mailman/listinfo/seasar-user
>>
> _______________________________________________
> Seasar-user mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-user
>
>


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