[Seasar-user:20274] Re: [DBFlute]OracleでDATE型カラムのインデックスが利用されない
kubo
[E-MAIL ADDRESS DELETED]
2010年 10月 22日 (金) 14:24:58 JST
久保(jflute)です。
しゃってんさん、色々と検証ありがとうございます。
状況が随分はっきりしてきましたね。
(小林さんのフォローに感謝感謝です)
> littleAdjustmentMap.dfprop あたりでのオプション扱いとして、
> 上記インナークラス部分を出力するような感じでもいいかもしれませんね。
勘がいいですねー。そういう感じのつもりです。
ただその前に、もう一つお願いしたいです。
oracle.sql.DATEを有効にした状態で、バッチ更新を使って、
該当のカラムを更新してみて下さい。
実はこちらで試してて、oracle.sql.Datum クラス内で
NullPointerException が発生してしまいました。
もしかしたら、検索条件のときだけ有効にするとか、
バッチ更新では除外するとか、何かしら処理を入れる
必要があるのかもしれません。
2010/10/22 しゃってん <[E-MAIL ADDRESS DELETED]>:
>> ((OraclePreparedStatement) ps).setDATE(index, new DATE(date));
> #
> # org.seasar.extension.dbcp.impl.ConnectionPoolImpl を利用している場合、
> # Connection connection =
> ((ConnectionWrapperImpl)dataSource.getConnection()).getPhysicalConnection();
> # としないとClassCastExceptionとなるんですね。。。
> #
> で実行した場合、時刻まで考慮された検索結果が取得され
> INDEX RANGE SCAN で検索が実行されました。
>
>
> 同様に
>> TnValueTypes.registerBasicValueType(keyType, new UtilDateAsTimestampType() {
>> @Override
>> public void bindValue(PreparedStatement ps, int index, Object
>> value) throws SQLException {
>> ps.setObject(index, new
>> DATE(DfTypeUtil.toTimestamp((java.util.Date) value)));
>> //super.bindValue(ps, index, value);
>> }
>> }); // switch
> #
> # SQLの組み立て時にFromToOption を利用すると時刻の指定ができなかったので
> # cb.query().setTargetDate_GreaterEqual(fromDate);
> # cb.query().setTargetDate_LessThan(toDate);
> # に変更しています。
> #
> の場合も時刻が考慮された検索結果が取得され、
> INDEX RANGE SCAN で検索が実行されました。
>
> littleAdjustmentMap.dfprop あたりでのオプション扱いとして、
> 上記インナークラス部分を出力するような感じでもいいかもしれませんね。
> ※あとFromToOptionで無変換で返すクラスがあればいいかなと。
>
>
> 2010年10月22日3:24 kubo <[E-MAIL ADDRESS DELETED]>:
>> 久保(jflute)です。
>>
>> しゃってんさん、まだDBFluteとしてどうするか考え中ですが、
>> DBFluteConfig にて、
>>
>> TnValueTypes.registerBasicValueType(keyType, valueType); // switch
>>
>> を
>>
>> TnValueTypes.registerBasicValueType(keyType, new UtilDateAsTimestampType() {
>> @Override
>> public void bindValue(PreparedStatement ps, int index, Object
>> value) throws SQLException {
>> ps.setObject(index, new
>> DATE(DfTypeUtil.toTimestamp((java.util.Date) value)));
>> //super.bindValue(ps, index, value);
>> }
>> }); // switch
>>
>> に差し替えて試してみて下さい。
>> (「DATE」は、oracle.sql.DATE です)
>> 恐らく、java.sql.Date を指定したときと同じ実行結果に
>> なるんじゃないかと思われます。
>> こちらでも、30万件のテーブルを用意して比べてみると、
>> 安定してパフォーマンスが改善されます。
>> (30万件程度なのでわずかですが10msほど安定して差がでます)
>>
>> ※これをどう整理して提供するかがポイントですね...
>>
>> 2010/10/21 kubo <[E-MAIL ADDRESS DELETED]>:
>>> 久保(jflute)です。
>>>
>>>>> O/Rマッパには厳しい話ですね。。。
>>>>> いっそリフレクションでガツンってのは
>>>>> やはり無理矢理過ぎるかなぁ。
>>>>
>>>> リフレクションでガツンとは?
>>>
>>> コンパイルレベルでDBMSのJDBCに依存したくないので、
>>> リフレクションで oracle.sql.DATE を利用するように処理する
>>> って感じですね。(もちろん、Oracleの場合に限り)
>>>
>>> 自動生成ありきのツールなので、oracle.sql.DATE を利用する
>>> ValueType を自動生成するのが現実的かもと今考えています。
>>> (OracleのDATE型の場合はそのValueTypeを使う)
>>> アプリは基本的にOracleのJDBCに依存しても問題ないので。
>>> (一応、オプションで)
>>>
>>> 2010/10/21 Koichi Kobayashi <[E-MAIL ADDRESS DELETED]>:
>>>> 小林 (koichik) です.
>>>>
>>>> Date: Thu, 21 Oct 2010 20:52:00 +0900
>>>> From: kubo <[E-MAIL ADDRESS DELETED]>
>>>> To: [E-MAIL ADDRESS DELETED]
>>>> Subject: [Seasar-user:20268] Re: [DBFlute]OracleでDATE型カラムのインデックスが利用されない
>>>>
>>>>> なるほど、そもそもDBMSに依存しないJDBCの型の中で、
>>>>> Oracle の DATE 型をぴったし当てはめられる型が存在しない
>>>>> というところですかね。
>>>>
>>>> そうですね.
>>>> JDBC および標準 SQL には日時 (日付と時刻) を
>>>> 扱うデータ型が基本的に TIMESTAMP 1 種類
>>>> (TZ 等は精度と同じ扱いとして) しかないのに対し,
>>>> Oracle には DATE と TIMESTAMP の 2 種類があり,
>>>> どちらも java.sql.Timestamp にマッピングするのが
>>>> 問題の根本でしょうね.
>>>> 歴史的なものなのでしょうがないですけど.
>>>>
>>>>> DATE型カラムのメタデータが:
>>>>> ojdbc5.jar = java.sql.Types.DATE
>>>>> ojdbc6.jar = java.sql.Types.TIMESTAMP
>>>>> となっていたので TIMESTAMP の指定で問題ないかなと
>>>>> 思ったのですが、(実際検索の動きとしては問題ないですが)
>>>>> 内部的には型違いと。
>>>>
>>>> Oracle の DATE が java.sql.Types.DATE なのは
>>>> 単純に間違ってますよね.
>>>> Oracle の DATE は日付型ではなく日時型なので.
>>>> ただし,Oracle の日時型には 2 種類ある...
>>>>
>>>>> > Oracle JDBC ドライバには oracle.sql.DATE という
>>>>> > 型があるので、java.sql.Timestamp からこの型に
>>>>> > 変換して、OraclePreparedStatement#setDATE() に
>>>>> > 渡すなんてのが Oracle 的に好ましいやり方なのかも。
>>>>>
>>>>> O/Rマッパには厳しい話ですね。。。
>>>>> いっそリフレクションでガツンってのは
>>>>> やはり無理矢理過ぎるかなぁ。
>>>>
>>>> リフレクションでガツンとは?
>>>>
>>>>
>>>> S2JDBC でも同じ問題は起こり得るので
>>>> 何か考えた方がいいかなぁ.
>>>> 幸い (?),S2JDBC では
>>>>
>>>> @Temporal(TemporalType.TIMESTAMP)
>>>> public java.util.Date xxx;
>>>>
>>>> public java.sql.Timestamp xxx;
>>>>
>>>> という 2 種類の書き方ができるので,前者の場合は
>>>> DATE,後者の場合は TIMESTAMP にマップして,
>>>> 前者は OracleDialect で oracle.sql.DATE に
>>>> 変換するとか.
>>>> S2JDBC-Gen と辻褄合うのかなぁ...
>>>>
>>>>
>>>> --
>>>> <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 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 メーリングリストの案内