[seasar-dotnet:1509] Re: [DBFlute] InternalBeanListMetaDataResultSetHandler の dataReader.Readの部分で時間がかかる。

kubo [E-MAIL ADDRESS DELETED]
2009年 10月 2日 (金) 15:55:58 JST


久保(jflute)です。

なんともこのレイヤがややこしいのは、
JDBCもADO.NETも同じですねぇ...

多分S2Daoでも同じ話で、Seasar.Extension.ADO.Types.ValueTypes
というクラスで何の型が何のValueTypeを利用するのかを決定します。
NVarcharやXmlTypeを全く利用してないのであれば、
ValueTypes.RegisterValueType()を使ってString型をDbType.AnsiStringの
ValueTypeに関連付けるようにしてしまうのもアリかもしれません。
(要動作確認)

一つのプロジェクトでVarcharとNVarcharが混じりまくってる場合は、
EntityのプロパティやCBでの型などにおいて、どちらもString型で
自動生成されるので、何かしら区別してあげる必要があります。
どちらかをString型じゃなくて独自の型で自動生成をして、
その独自の方に対してValueTypesで関連付けをするようにします。
ただ、このやり方だと片方はString型ですが、片方は独自の型になる
のでアプリケーション上で扱いづらいかもですね。

#
# EntityでValueTypeアノテーション(属性)を指定して...って
# S2Dao.NETでこれってサポートされてたっけかな!?
#


2009/10/2 西山 はじめ <[E-MAIL ADDRESS DELETED]>:
> 西山(hajmeni)です。
>
> 進展ありましたので、報告いたします。
> 割と特殊な環境過ぎて、参考にならないと思いますが。
>
> まず、Oracleの型と .NetのDbTypeのマッピングが DataDirect ADO  for .NET では以下のようになります。
>
> +-----------------------+-------------------+
> |System.Data.DbType     |OracleDbType       |
> +-----------------------+-------------------+
> |Object                 |BFile              |
> |Object                 |Blob               |
> |Byte                   |Byte               |
> |AnsiStringFixedLength  |Char               |
> |Object                 |Clob               |
> |Date                   |Date or Timestamp1 |
> |DateTime               |Date or Timestamp* |
> |Time                   |Date or Timestamp* |
> |Double                 |Double             |
> |Single                 |Float              |
> |Int16                  |Int16              |
> |Int32                  |Int32              |
> |Int64                  |Int64              |
> |String                 |Long               |
> |Binary                 |LongRaw            |
> |StringFixedLength      |NChar              |
> |Object                 |NClob              |
> |GUID                   |Not supported      |
> |Object                 |Not supported      |
> |Boolean                |Number             |
> |Currency               |Number             |
> |Decimal                |Number             |
> |VarNumeric             |Number             |
> |String                 |NVarChar or XmlType|
> |Binary                 |Raw                |
> |-                      |RowId              |
> |Sbyte                  |Sbyte              |
> |DateTime               |Timestamp          |
> |DateTime               |TimestampLocal     |
> |DateTime               |TimestampWithTZ    |
> |Uint16                 |Uint16             |
> |Uint32                 |Uint32             |
> |Uint64                 |Uint64             |
> |AnsiString             |VarChar            |
> |XML                    |XmlType            |
> +-----------------------+-------------------+
>
> この表を見ると、System.Data.Stringは NVarchar or XmlType に
> マッピングされ、System.Data.AnsiString が VarChar にマッピン グされます。
>
> DataDirectのサポートに問い合わせた結果、指定のカラム型と、実 際のカラム型に違いがある為、不必要なデータ型変換が発生するこ
> とで性能劣化しているのではないかとのことでした。
>
> 詳しい調査は再現環境を渡さないといけないとの事でしたが、
> 「export した後に 同じデータを import すると再現しなくなる」
> 為、すぐには解決しそうにありませんでした。
>
> DBFluteでの、System.Dataの型指定を変更できれば良いと思うので すが、いい案ありますでしょうか。
> (中を見たら、Seasar.Estension.ADO.IValueTypeを利用している ようでした)
>
> ひとまず、DataReader.Readの直前で DataType.Stringが指定され
> ていた場合は、DataType.AnsiStringで上書きするようにしています。
>
> 以上、よろしくお願いいたします。
>
> [2009/09/30 23:07] kubo さんは書きました。:
>>
>> 久保(jflute)です。
>>
>> 複雑な問題のようですね...
>> 詳細な報告ありがとうございます。
>> (Javaで全く同じことしてどうなるか気になりますねぇ...)
>>
>> 2009/9/30 西山 はじめ <[E-MAIL ADDRESS DELETED]>:
>>>
>>> 西山(hajimeni)です。
>>>
>>> DBFlute.NET(S2Dao.NET含む)と自前での実装の違いを詳細に調べ た結果、原因がわかりましたので報告いたします。
>>>
>>> 詳細な条件はまだ、不明です。ただし、調査している限りの情報では、
>>> ============================================================
>>> ・EXISTS句を使用している。
>>> ・EXISTS句の中でJOINを行っている。
>>> ・JOINしたテーブルのカラムに対してバインド変数を使用して、中 間一致条件を設定している。(LIKE '%あああ%')
>>> ・上記のバインド変数は3つ目以降である(これは違うかもしれま せん)
>>> ・上記のバインド変数に対応した、IDbDataParameterのDBTypeに、 DbType.String が設定されている。
>>> ============================================================
>>> 以上の条件を全て満たした場合のみ、dataReader.Readが遅くなる という現象でした。
>>>
>>> 単純な回避手段は、DbType に DbType.AnsiString を指定すること でした。
>>>
>>> 独自実装で再現しなかった理由は、DbType の設定を何も行ってい なかったからでした。
>>>
>>>
>>> これ以上は、DataDirect ADO for .NET の問題であると思われます ので、開発元のサポートに問い合わせたいと思います。
>>>
>>> お手数をお掛けいたしました。ありがとうございます。
>>>
>>> 以上よろしくお願いいたします。
>>>
>>> [2009/09/29 22:55] kubo さんは書きました。:
>>>>
>>>> 久保(jflute)です。
>>>>
>>>>> B. OracleのAPIに依存しない形で実装(IDbCommandとか)
>>>>
>>>> あと、ConnectionをQuillのDataSourceから
>>>> 取得するようにしてみて下さい。
>>>>
>>>> 2009/9/29 kubo <[E-MAIL ADDRESS DELETED]>:
>>>>>
>>>>> 久保(jflute)です。
>>>>>
>>>>> ありがとうございます。
>>>>> これはもうOracle内部での話になるかもですね。
>>>>> 逆に独自実装で再現しないのが不思議なところです。
>>>>>
>>>>> 独自実装ですが、
>>>>>
>>>>> A. トランザクションを開始した状態で実行
>>>>> B. OracleのAPIに依存しない形で実装(IDbCommandとか)
>>>>> C. IDbCommandをTnBasicCommandFactory.CreateCommand()
>>>>> 経由で取得して実行
>>>>>
>>>>> をお試し下さい。
>>>>> 違いがCommandFactoryとコネクションの生成の仕方とか
>>>>> そういうのしか思いつかないですね。。。
>>>>>
>>>>> 2009/9/29 西山 はじめ <[E-MAIL ADDRESS DELETED]>:
>>>>>>
>>>>>> 西山(hajimeni)です。
>>>>>>
>>>>>> IDataReaderは、
>>>>>> DataDirect Connect for ADO.NET 3.2 で提供されている。
>>>>>>
>>>>>> DDTek.Oracle.OracleDataReader
>>>>>>
>>>>>> となります。
>>>>>>
>>>>>> QuillのDataProviderでは提供されていなかった為、
>>>>>> DataProviderを継承したクラスを作成しています。
>>>>>>
>>>>>> Public Class DDTekOracle
>>>>>>  Inherits DataProvider
>>>>>> Public Sub New()
>>>>>>  ConnectionType = "DDTek.Oracle.OracleConnection"
>>>>>>  CommandType = "DDTek.Oracle.OracleCommand"
>>>>>>  ParameterType = "DDTek.Oracle.OracleParameter"
>>>>>>  DataAdapterType = "DDTek.Oracle.OracleDataAdapter"
>>>>>> End Sub
>>>>>> End Class
>>>>>>
>>>>>>
>>>>>>
>>>>>> CreateDataReaderの挙動ですが、
>>>>>>
>>>>>> 1.ExecuteReader で OracleDataReader が生成される。
>>>>>> 2.if (!FetchNarrowingBeanContext.IsExistFetchNarrowingBeanOnThread())
>>>>>> {
>>>>>> が false となり次の処理へ。
>>>>>>
>>>>>> 2.if (!IsUseFetchNarrowingResultSetWrapper(cb)) {
>>>>>> が true となり 1 で生成した OracleDataReader を return
>>>>>>
>>>>>> となっています。
>>>>>>
>>>>>>
>>>>>> [2009/09/29 20:57] kubo さんは書きました。:
>>>>>>>
>>>>>>> 久保(jflute)です。
>>>>>>>
>>>>>>> ありがとうございます。
>>>>>>> なるほど、ターゲットは完全に
>>>>>>> IDataReaderのRead()メソッドですね。
>>>>>>>
>>>>>>> そのIDataReaderのGetType()を見て頂けます?
>>>>>>> もし、FetchNarrowingResultSetWrapperのRead()で
>>>>>>> どの処理が時間が掛かっているのか調べて下さい。
>>>>>>> (って、大した処理してないんですけどね..)
>>>>>>>
>>>>>>> あと、FetchNarrowingResultSetFactoryのCreateDataReader()
>>>>>>> 内の挙動も調べて頂ければと。
>>>>>>>
>>>>>>> 2009/9/29 西山 はじめ <[E-MAIL ADDRESS DELETED]>:
>>>>>>>>
>>>>>>>> 西山(hajimeni)です。
>>>>>>>>
>>>>>>>> すいません。
>>>>>>>> ログの部分ですが、コンソールに出力した為、前後がずれてしまっ ています。
>>>>>>>> [while:Before]:2009/09/29 20:02:56
>>>>>>>> は、SQL文表示の後、
>>>>>>>> [Loop:Start]:2009/09/29 20:03:13
>>>>>>>> の前が正しいです。
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> [2009/09/29 20:20] 西山 はじめ さんは書きました。:
>>>>>>>>>
>>>>>>>>> 西山(hajimeni)です。
>>>>>>>>>
>>>>>>>>> 返答ありがとうございます。
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 自前の実装でもバインド変数を利用しています。
>>>>>>>>> DbParameterを追加しています。
>>>>>>>>>
>>>>>>>>> ============================================================
>>>>>>>>> Dim conn As OracleConnection =
>>>>>>>>>  New OracleConnection("接続文字列")
>>>>>>>>> conn.Open()
>>>>>>>>> Dim sqlCommand As OracleCommand =
>>>>>>>>>  New OracleCommand()
>>>>>>>>> sqlCommand.Connection = conn
>>>>>>>>> sqlCommand.CommandText = sql
>>>>>>>>> sqlCommand.Parameters.Add(New OracleParameter("?", "0"))
>>>>>>>>> sqlCommand.Parameters.Add(New OracleParameter("?", "0"))
>>>>>>>>> sqlCommand.Parameters.Add(New OracleParameter("?", "%あああ%"))
>>>>>>>>> Dim sqlReader As OracleDataReader =
>>>>>>>>> sqlCommand.ExecuteReader()
>>>>>>>>> While sqlReader.Read
>>>>>>>>>  _logger.Debug("・・・・・・・・1行読み取り")
>>>>>>>>> End While
>>>>>>>>>
>>>>>>>>> ============================================================
>>>>>>>>>
>>>>>>>>> また、InternalBeanListMetaDataResultSetHandler の while文で
>>>>>>>>> すが、dataReader.Read
>>>>>>>>> の行が遅いです。
>>>>>>>>>
>>>>>>>>> A~Dまでは一瞬です。
>>>>>>>>> while文を囲って計測した結果を添付します。
>>>>>>>>>
>>>>>>>>> [while:Before]:2009/09/29 20:02:56
>>>>>>>>>
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:13
>>>>>>>>>
>>>>>>>>> の間に、while(dataReader.Read)メソッドがあります。
>>>>>>>>> 今回は17秒かかっています。
>>>>>>>>>
>>>>>>>>> ちなみに、アプリケーションを起動したまま連続して実行してもほ ぼ同等の時間がかかります。
>>>>>>>>>
>>>>>>>>> System.Console.WriteLine("[while:Before]:" + DateTime.Now);
>>>>>>>>> while (dataReader.Read()) {
>>>>>>>>>  System.Console.WriteLine("  [Loop:Start]:" + DateTime.Now);
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> SQLや結果、クラス名は置換させてもらいました。
>>>>>>>>>
>>>>>>>>> ******************************
>>>>>>>>> Dummy.DBFlute.AllCommon.S2Dao.S2DaoMetaDataExtension: DEBUG
>>>>>>>>> 2009-09-29
>>>>>>>>> 20:02:56,484 [10] ...Initializing sqlCommand for SelectList().
>>>>>>>>> Dummy.DBFlute.AllCommon.XLog: DEBUG 2009-09-29 20:02:56,484 [10]
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> /===========================================================================
>>>>>>>>> Dummy.DBFlute.AllCommon.XLog: DEBUG 2009-09-29 20:02:56,484 [10]
>>>>>>>>> RecipeBhv.SelectList()
>>>>>>>>> Dummy.DBFlute.AllCommon.XLog: DEBUG 2009-09-29 20:02:56,484 [10]
>>>>>>>>> =====================/
>>>>>>>>> [while:Before]:2009/09/29 20:02:56
>>>>>>>>> Seasar.Framework.Util.DataSourceUtil: DEBUG 2009-09-29 20:02:56,546
>>>>>>>>> [10]
>>>>>>>>> 論理的なコネクションを取得しました
>>>>>>>>> Dummy.DBFlute.AllCommon.QLog: DEBUG 2009-09-29 20:02:56,546 [10]
>>>>>>>>> select  dflocal.PARENT_ID as PARENT_ID, dflocal.PARENT_NO as
>>>>>>>>> PARENT_NO,
>>>>>>>>> dflocal.PARENT_NAME as PARENT_NAME, dflocal.MAG_ID as MAG_ID,
>>>>>>>>> dflocal.FENAME
>>>>>>>>> as FENAME, dflocal.SUBTITLE as SUBTITLE, dflocal.SEID as SEID,
>>>>>>>>> dflocal.SEVOLUME as SEVOLUME, dflocal.NO_FROM as NO_FROM,
>>>>>>>>> dflocal.NO_TO
>>>>>>>>> as
>>>>>>>>> NO_TO, dflocal.SUP as SUP, dflocal.CALORIE as CALORIE,
>>>>>>>>> dflocal.DUMMY_UNIT as
>>>>>>>>> DUMMY_UNIT, dflocal.DUMMY_CALCULATION as DUMMY_CALCULATION,
>>>>>>>>> dflocal.SALINITY
>>>>>>>>> as SALINITY, dflocal.SERVES as SERVES, dflocal.SET_TYPE_NAME as
>>>>>>>>> SET_TYPE_NAME, dflocal.MAIN_PARENT_ID as MAIN_PARENT_ID,
>>>>>>>>> dflocal.COOKING_ADVISOR_ID as COOKING_ADVISOR_ID,
>>>>>>>>> dflocal.STYLIST_ID
>>>>>>>>> as
>>>>>>>>> STYLIST_ID, dflocal.CAMERAMAN_ID as CAMERAMAN_ID, dflocal.USABLE as
>>>>>>>>> USABLE,
>>>>>>>>> dflocal.REPRINT_STATUS as REPRINT_STATUS, dflocal.DELETED as
>>>>>>>>> DELETED,
>>>>>>>>> dflocal.REGISTER_USER as REGISTER_USER, dflocal.REGISTER_PROCESS as
>>>>>>>>> REGISTER_PROCESS, dflocal.REGISTER_DATETIME as REGISTER_DATETIME,
>>>>>>>>> dflocal.UPDATE_USER as UPDATE_USER, dflocal.UPDATE_PROCESS as
>>>>>>>>> UPDATE_PROCESS, dflocal.UPDATE_DATETIME as UPDATE_DATETIME,
>>>>>>>>> dflocal.VERSION_NO as VERSION_NO
>>>>>>>>>  from PARENT dflocal
>>>>>>>>>  where dflocal.DELETED = '0'
>>>>>>>>>  and exists (select dfsublocal_0.PARENT_ID
>>>>>>>>>               from PARENT_OTHER dfsublocal_0
>>>>>>>>>                 left outer join OTHER dfrelation_0 on
>>>>>>>>> dfsublocal_0.OTHER_ID = dfrelation_0.OTHER_ID
>>>>>>>>>              where dfsublocal_0.PARENT_ID = dflocal.PARENT_ID
>>>>>>>>>                and dfsublocal_0.DELETED = '0'
>>>>>>>>>                and dfrelation_0.OTHER_NAME like '%あああ %' escape '|'
>>>>>>>>>     )
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:13
>>>>>>>>>  [CreateColumnNames:Before]:2009/09/29 20:03:13
>>>>>>>>>  [CreateColumnNames:After ]:2009/09/29 20:03:14
>>>>>>>>>  [CreateColumnMetaData:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateColumnMetaData:After ]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:14
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:14
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:32
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:32
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:32
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:32
>>>>>>>>>  [Loop:Start]:2009/09/29 20:03:32
>>>>>>>>>  [CreateRow:Before]:2009/09/29 20:03:32
>>>>>>>>>  [CreateRow:After ]:2009/09/29 20:03:32
>>>>>>>>>  [Loop:Continue]:2009/09/29 20:03:32
>>>>>>>>> [while:After]:2009/09/29 20:03:32
>>>>>>>>> Seasar.Framework.Util.ConnectionUtil: DEBUG 2009-09-29 20:03:32,797
>>>>>>>>> [10]
>>>>>>>>> 論理的なコネクションを閉じました
>>>>>>>>> Dummy.DBFlute.AllCommon.XLog: DEBUG 2009-09-29 20:03:32,797 [10]
>>>>>>>>> ===========/ [01m16s313ms (10) first=
>>>>>>>>> {・・・・・・・・・・・・・・・・・・・・・・・・・・・}]
>>>>>>>>> Dummy.DBFlute.AllCommon.XLog: DEBUG 2009-09-29 20:03:32,828 [10]
>>>>>>>>> ******************************
>>>>>>>>>
>>>>>>>>> 以上よろしくお願いいたします。
>>>>>>>>>
>>>>>>>>> [2009/09/29 17:16] kubo さんは書きました。:
>>>>>>>>>>
>>>>>>>>>> 久保(jflute)です。
>>>>>>>>>>
>>>>>>>>>> 西山さん、こんにちは
>>>>>>>>>>
>>>>>>>>>> 20秒はちょっと異常ですね。
>>>>>>>>>> 情報を整理させて下さい。
>>>>>>>>>>
>>>>>>>>>> まず、コストターゲットがSQL実行なのかマッピングなのか?
>>>>>>>>>> っていうところですが、既に自前の実装だと遅くならない
>>>>>>>>>> とのことですが、その自前の実装はバインド変数を利用して
>>>>>>>>>> の実行と考えてよろしいでしょうか?
>>>>>>>>>> Yesならマッピングでほぼ確定かと思いますのでOKです。
>>>>>>>>>>
>>>>>>>>>> そして、実際に「while (dataReader.Read()) {」のループが遅い
>>>>>>>>>> とのことですが、ループ内のそれぞれの処理でどれが遅いのか
>>>>>>>>>> 計って頂けますでしょうか?
>>>>>>>>>> (具体的に一つ一つの処理の時間を計測願います)
>>>>>>>>>>
>>>>>>>>>> <A>
>>>>>>>>>> columnNames = CreateColumnNames(dataReader.GetSchemaTable());
>>>>>>>>>> ※最初の一回だけ実行される
>>>>>>>>>>
>>>>>>>>>> <B>
>>>>>>>>>> columns = CreateColumnMetaData(columnNames);
>>>>>>>>>> ※最初の一回だけ実行される
>>>>>>>>>>
>>>>>>>>>> <C>
>>>>>>>>>> Object row = CreateRow(dataReader, columns);
>>>>>>>>>> ※毎ループ実行される
>>>>>>>>>>
>>>>>>>>>> <D>
>>>>>>>>>> その他リレーション周りの処理
>>>>>>>>>> ※親テーブル(基点テーブル)のみの取得なので実行されないはず
>>>>>>>>>>  --> skipRelationLoopがtrueのはず
>>>>>>>>>>
>>>>>>>>>> 2009/9/29 西山 はじめ <[E-MAIL ADDRESS DELETED]>:
>>>>>>>>>>>
>>>>>>>>>>> お世話になっております。
>>>>>>>>>>> 西山(hajimeni)です。
>>>>>>>>>>>
>>>>>>>>>>> DBFluteを利用してSQLクエリーを実行した時に、なぜか時間がか
>>>>>>>>>>> かってしまいます。
>>>>>>>>>>> 同じクエリーを自力で構築して実行した際には、時間がかかること
>>>>>>>>>>> が無く、原因追求に戸惑っています。
>>>>>>>>>>>
>>>>>>>>>>> デバッグで追ってみたところ、
>>>>>>>>>>> InternalBeanListMetaDataResultSetHandlerクラス、
>>>>>>>>>>> Handleメソッド内の
>>>>>>>>>>> while (dataReader.Read()) {
>>>>>>>>>>> ・・・
>>>>>>>>>>> 部分で時間がかかっているようでした。
>>>>>>>>>>>
>>>>>>>>>>> DBFlute内で作成されたDbCommoandやDbParameter、DbConnectionと
>>>>>>>>>>> 同等のものを自力で作った際には、dataReader.Reader部分でも時
>>>>>>>>>>> 間がかからず処理されています。
>>>>>>>>>>>
>>>>>>>>>>> お手数ですが、調査方法等、何かアドバイスしていただけると幸い
>>>>>>>>>>> です。
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> [環境]
>>>>>>>>>>> DB: Oracle9.2.0.5
>>>>>>>>>>> .NET: 2.0
>>>>>>>>>>> 開発環境: VisualBasic 2008
>>>>>>>>>>> DBFlute.NET: 0.8.9.2
>>>>>>>>>>> 接続: DataDirect Connect for ADO.NET 3.2
>>>>>>>>>>>
>>>>>>>>>>> DBFluteでの実行時間:
>>>>>>>>>>>  約20秒程度(ログから)
>>>>>>>>>>> 自力でCommand、Readerを構築したときの実行時間
>>>>>>>>>>>  1~2秒程度
>>>>>>>>>>>
>>>>>>>>>>> ///////////////
>>>>>>>>>>> [親テーブル]1:n[子テーブル]n:1[別テーブル]
>>>>>>>>>>>
>>>>>>>>>>> [親テーブル]  7,000件
>>>>>>>>>>> [子テーブル] 60,000件
>>>>>>>>>>> [別テーブル]  2,000件
>>>>>>>>>>>
>>>>>>>>>>> というテーブルで、親テーブルを結果として取得する為に
>>>>>>>>>>> 子テーブルをExistsSubQueryにし、
>>>>>>>>>>> 別テーブルの検索条件で絞り込んでいます。
>>>>>>>>>>> これに対して1000件絞込みまで行っています。
>>>>>>>>>>>
>>>>>>>>>>> Dim cb As New 親テーブルCB()
>>>>>>>>>>> cb.Query().Deleted_Equal_False()
>>>>>>>>>>> cb.Query().
>>>>>>>>>>>  Exists別テーブルList(AddressOf GetAddressOfSubQuery)
>>>>>>>>>>>
>>>>>>>>>>> Function GetAddressOfSubQuery() As SubQuery(Of 子テーブルCB)
>>>>>>>>>>>  subCB.Query().SetDeleted_Equal_False()
>>>>>>>>>>>  subCB.Query().Query別テーブル().
>>>>>>>>>>>  SetName_LikeSearch(_name,
>>>>>>>>>>>   New LikeSearchOption().LikeContain())
>>>>>>>>>>> End Function
>>>>>>>>>>>
>>>>>>>>>>> [SQL]
>>>>>>>>>>> ///////////////
>>>>>>>>>>> SELECT
>>>>>>>>>>>  親テーブル.ID
>>>>>>>>>>> FROM 親テーブル
>>>>>>>>>>> WHERE 親テーブル.DELETED = '0'
>>>>>>>>>>>  AND EXISTS (SELECT 子テーブル.ID
>>>>>>>>>>>          FROM 子テーブル
>>>>>>>>>>>            LEFT JOIN 別テーブル ON 子テーブル.ID = 別
>>>>>>>>>>> テーブルID
>>>>>>>>>>>          WHERE 子テーブル.PARENT_ID = 親テーブル.ID
>>>>>>>>>>>            AND 子テーブル.DELETED = '0'
>>>>>>>>>>>            AND 別テーブル.NAME LIKE '%あああ%' ESCALE '|')
>>>>>>>>>>> ///////////////
>>>>>>>>>>> テーブル名は、置換させてもらっております。
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 以上よろしくお願いいたします。
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>>>> 西山 はじめ
>>>>>>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>>>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> seasar-dotnet mailing list
>>>>>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>>>>>>
>>>>>>>> --
>>>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>> 西山 はじめ
>>>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>>>
>>>>>>>> _______________________________________________
>>>>>>>> seasar-dotnet mailing list
>>>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>>>
>>>>>>>
>>>>>> --
>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>> 西山 はじめ
>>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>>>>
>>>>>> _______________________________________________
>>>>>> seasar-dotnet mailing list
>>>>>> [E-MAIL ADDRESS DELETED]
>>>>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>>>>
>>>>
>>>>
>>>
>>> --
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  西山 はじめ
>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>
>>> _______________________________________________
>>> seasar-dotnet mailing list
>>> [E-MAIL ADDRESS DELETED]
>>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>>
>> _______________________________________________
>> seasar-dotnet mailing list
>> [E-MAIL ADDRESS DELETED]
>> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>>
>>
>>
>
>
> --
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  西山 はじめ
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> _______________________________________________
> seasar-dotnet mailing list
> [E-MAIL ADDRESS DELETED]
> https://ml.seasar.org/mailman/listinfo/seasar-dotnet
>


seasar-dotnet メーリングリストの案内