データセットデザイナの反応が遅い

データセットデザイナの反応が遅い、とお嘆きのあなた。

そりゃまあ、何か操作をするたびに DB サーバに確認に行ったり取得に行ったりするわけですから、ある程度時間がかかってしまうのはやむを得ないとして。
でも数秒~数十秒、ヘタすると数十分待たされてしまうのでは、とても実用的とは言えません。

ということで、データセットデザイナの反応を劇的に上げるチューニングをお話ししてみたいと思います。

…劇的、はちょっとハッタリかもしれませんすいません。


検証環境 自作マシン(Core2QuadQ9400 2.66GHz/4GB)

Windows7 Ultimate(6.1.7600) – x86
VisualStudio2008Pro(VB) 9.0.30729.1SP/.NET Framework 3.5SP1
Oracle Database 11g 11.1.0.6.0
Oracle Developer Tools for Visual Studio 11.1.0.7.20

Windows XP Professional SP3
VisualStudio2008Pro(VB) 9.0.21022.8/.NET Framework 3.5SP1
Oracle Developer Tools for Visual Studio.NET 11.1.0.6.20

前振りとして、やはり DB サーバとの通信速度を上げられるだけ上げておきましょう。

特にいまどき 10M・100M ではやはりトロく。予算的な問題もあるとは思いますが、最低 1000M とか カテゴリ 5 とかくらいには。数千円くらいの出費で済みますし。
イントラネットなどでそうそう全体的な通信速度の底上げができない、DB サーバが複数のプロジェクト共有で勝手に部品の追加交換ができないなどの事情がある場合は、いっそ開発マシンに作業用の Oracle DB をインストールしてしまうという手もあります。
これもお客様のデータを取り扱う等の理由で勝手にサーバを立てることができない等処々の制限もあるとは思いますが、なんとか可能な範囲でできるだけ。

イントラにつながっている場合は、開発マシンのアクセス可能な範囲を狭めるという手もあります。
これもネットワーク管理者と打ち合わせたり、開発マシンを複数のプロジェクト環境にアクセスできる状態を保つ必要がある等処々の事情もあるとは思いますが、これもなんとか可能な範囲でできるだけ。


で、本論。
データセットデザイナで DB サーバへのアクセス範囲を狭めてやればいいんですね。

たとえば、TableAdapter 構成ウィザードの「データ接続の選択」画面で [新しい接続] をクリック → 「データソースの選択」ダイアログで[Oracle データベース]-[Oracle Data Provider for .NET] → [続行] をクリック → 「接続の追加」画面まで来たとして。

[接続の詳細] タブで接続文字列を構成する情報を入力してから、[フィルタの適用] タブへ切り替えます。

11.1.0.6.20 の場合はこんな画面になります。

[表示されるスキーマ] が上図の状態だと、最悪です。
他プロジェクト用のスキーマや、まずめったにアクセスに行かないシステムのスキーマまですべて表示範囲になってしまっています。これでは、DB オブジェクトの一覧表示や検索に行く際に、使わないスキーマやオブジェクトまでいちいち参照するという動作になってしまいます。

ので、開発に不要なスキーマは全部 [使用可能なスキーマ] リストボックスに追いやってしまいましょう。
シノニムも使わないのであれば、[パブリック・シノニムの表示] チェックボックスのチェックも外します。

これだけで、相当速くなります。

私の環境ではクエリビルダの起動 → 「テーブルの追加」ダイアログ表示までにかかる時間が、全スキーマ対象だと約 17 秒 → 瞬時~ 1 秒まで改善しました。

11.1.0.7.20 だと、より細かくフィルタリングをかけられます。

スキーマだけではなく、コレクション(表とかビューとか)も絞り込めます。
11.1.0.6.20 ではチェックボックスだった [Display Public Synonyms](パブリック・シノニムの表示) も表に取り込まれています。
さらに [Select a collection] を [Tables][Views] などに切り替えると、それぞれのコレクションの中でさらに細かく対象条件を指定できます。

TableAdapter で「新しい接続」を設定すると、[サーバーエクスプローラ]ウィンドウの [データ接続] ノードにその接続情報が登録されます。
ただし、あらかじめ同じデータソース・ユーザー名での接続情報がサーバーエクスプローラに登録されていると、TableAdapter 登録ウィザードでの「新しい接続」は無視され、サーバーエクスプローラの接続情報で置き換えられます。

つまり、接続情報に付帯するフィルタリング情報は、ソースコード側ではなくサーバーエクスプローラ (VS IDE) 側に保持されるわけです。

同一のデータソース・スキーマに対する接続情報は、サーバーエクスプローラへはひとつしか登録できません。たとえばフィルタリング情報等を変えて複数持たせようとしても、2 つ目以降の登録は無視されます。


もひとつ。

TableAdapter 構成ウィザードの「SQL ステートメントの入力」画面で [詳細オプション] クリックで表示される「詳細設定」ダイアログ。

直接データセットから更新 (Insert/Update/Delete) をかけないのであれば、できるだけここの [INSERT、UPDATE、および DELETE ステートメントの生成] チェックボックスのチェックは外しておくことをお勧めします。

更新系のソースを自動生成すると、参照系だけのソースに比較してけっこうな時間がかかります。

また、元となる SQL 文で複数のテーブルを結合かけていたり、単テーブルでも主キーフィールドが複数あってそのすべてが取り込まれていない状態だと、TableAdapter 構成ウィザードは更新できるあらゆる可能性を考えた上で「更新できません」という判断をしますので、ものすごく時間がかかります。
ひどい時には、ここから完了までの手順の中で数十分考え込んだり、挙句の果てに IDE ごと落ちたりします。

単テーブルですべての主キーフィールドを取り込んでいる状態でも、「すべてのフィールド」を取り込んでいない場合には、Update・Delete ステートメントは生成されますが、Insert ステートメントは生成されません。
これはテーブルのフィールド数にもよりますが、この判断に費やされる時間も意外とばかにならなかったりします。

「更新を直接データベースに送信するためのメソッドを作成する」チェックボックスも同様です。
ここも、更新できない SQL 文の際にチェックがついていると、最悪 IDE ごと落ちます。


ということで、データセットデザイナの反応を高速化するポイントは 2 つ。

  • サーバーエクスプローラの接続情報で、使用しないオブジェクトは参照しないようにフィルタリングをかける。
  • 更新しないテーブルアダプタでは、更新系ステートメントの生成を行うチェックをはずす。

なんか他にもポイントがありそうな気もしますが、とりあえず現時点で私がわかっているのはここまでということでひとつ。

3 コメント

  1. mok より:

    引き続き、参考にさせて頂いております。
    私の環境は下記のような環境です。

    Windows7 Professional – x86
    VisualStudio2008Pro(VB) 9.0.30729.1SP/.NET Framework 3.5SP1
    Oracle Developer Tools for Visual Studio 11.1.0.7.20

    Windows Server 2008
    Oracle Database 11g 11.1.0.7.0

    今現在、データセットデザイナの反応が非常に遅い状況となっています。
    接続としては、本稿のとおりで、必要なスキーマ/オブジェクトに対するフィルタが
    かかっていますが、クエリウィザードの起動や、その後の「次へ」以降が
    非常に重いです・・・。というよりは、VSがハングしたりもします。
    VSのプロセス強制終了、再起動後ですと、同一の処理でもかなり早く終わったり
    するので、VSのプロセスに負荷が異常にかかったりしているのでしょうか・・・。

    いずれにしても詳細は不明です。
    猿頁様は、そういった状況等発生してたりしますか?
    参考までに、コメント頂けると幸いです。

  2. さるべーじ より:

    ご覧いただき、ありがとうございます。

    > そういった状況等発生してたりしますか?

    うーん、いろいろ回避策は練っておりますが、やはり重くなる時はなります。
    ハングもします。「(応答なし)」になってしまったら、さっさとプロセス潰して再起動かけた方が早いやー、となるのはこちらでも同様です。

    変に重い時は、データセットファイル (.xsd) を削除して作り直したりしています。
    どうも .xsd に埋め込まれているデフォルト接続情報が悪さをしている場合があるようで。

    私はSQL 文や各種設定を再作成するため用に、設定の吸い上げツールを作っています。
    つたないできですが、近日公開するつもりです。

    また、サブクエリ等が複雑に絡んだ SQL 文は、解析に時間がかかります。
    あまりに遅い場合は、ダミーでDataTableだけ作って置いて実際の SQL 文は CommandText に直接記述または別クエリとして追加、なんて手も使っています。
    あるいは、SQL を View で用意、データセット側では単純な View アクセスとして、構文解析にかかる時間を回避したりもしています。

    ネタはたまってきていますので、時間が取れればもう少しエントリを増やすつもりです。
    その節には、またお付き合いいただけると嬉しいです。

  3. mok より:

    そうですか、私もハングした際や重くなった際には、
    プロセスを潰して再起動しておりました。

    猿頁様も同様の事象や処置がありましたので、
    私の環境や構成の問題点では無かったことで一安心しております。

    TableAdapterにより、DataSetの内部をこねくりまわす実装から
    よりオブジェクト指向によるメンバアクセスが可能となった点、
    後は、クエリウィザードにより、SQL文が実行時ではなく実装時に
    妥当性検証される点等、適用の価値から期待度が大きいですよね。

    「重い、遅い、挙動が変」といった部分はケースバイケースで回避しつつ、
    有効活用したいと思います。

    次ネタの投稿、設定の吸い上げツール等、期待しております。
    コメントありがとうございました。

コメントを投稿