- PR -

ADO接続にてMDB容量増加に伴うレスポンスの低下(VB.NET)

投稿者投稿内容
むさし
会議室デビュー日: 2003/07/07
投稿数: 8
投稿日時: 2005-10-19 23:24
こんにちは、VB.NET2002(Winアプリ)にてファイルサーバーにおいてあるAccessとの接続を行いデータを収集・集計などを行うツールを作成しております。

ツールの利用者は300人程度で、対して利用者がアクセスするデータは10000件ですが同時に使用する事がなく、規模的にこれくらいのシステムが良いと判断し作成しました。
当初テスト段階では1000件程度のデータを扱っていてMDB自体は3MB程度で、1〜4秒ほどあれば結果が返ってくるようでしたがいざ本番用のデータをいれたところ15MB程度になりレスポンスタイムは1分を超えるようになってしまいました・・・。

当初機能などを追加したのが影響かとおもったのですがデータを削ってみるとレスポンスが早くなるという症状から容量の増加が原因ではないかとおもっております。

基本的にDataReaderにて接続しておりますがDataGridなどに表示したりする場合などにはDataSetを利用しています。

明らかにユーザーの立場から見て我慢の出来る範囲を超えていると思いますのでなんとか対応したいとおもってます。
この症状のお分かりになるようでしたらよろしくお願いいたします。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2005-10-20 01:56
unibon です。こんにちわ。

引用:

むさしさんの書き込み (2005-10-19 23:24) より:
当初テスト段階では1000件程度のデータを扱っていてMDB自体は3MB程度で、1〜4秒ほどあれば結果が返ってくるようでしたがいざ本番用のデータをいれたところ15MB程度になりレスポンスタイムは1分を超えるようになってしまいました・・・。


とりあえずは、データー転送の帯域幅を測ってみることをお勧めします。もしも LAN の 10Mbps や 100Mbps よりもずっと低い速度だったら、原因は他のところにある可能性があります(ネットワークの問題等)。ついでに CPU の使用率も見ても補助的な参考になります。いずれも、すぐに計測できます。

引用:

むさしさんの書き込み (2005-10-19 23:24) より:
基本的にDataReaderにて接続しておりますがDataGridなどに表示したりする場合などにはDataSetを利用しています。


これらのクラスは使ったことがないのであまり個別のことは私は分からないのですが、MDB に対する検索はどのようにおこなわれているのでしょうか?もしもインデックスがないフィールドを検索キーにすれば、結局は MDB の 15MB を丸ごと転送するのとほとんど同じことになり、サーバー・クライアントではない MDB を使う限りはしかたがないです。現在、インデックスを適切に付けてあるでしょうか?
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2005-10-20 06:28
むさしさん、おはようございます。

可能であれば、SQLServer か Oracle など(小規模案件ならMSDEでも可)に切り替えた方が幸せになれると思います。たとえ同時アクセスは無くとも、ネットワーク上で公開するようなシステムには、Jet Database Engine は向いていないと思います。

いわゆる RDBMS の場合、問い合わせを処理するのはサーバ側で、 クライアントはその結果だけを受け取ります。
しかし Jet の場合、問い合わせを処理するのは、アプリケーションを実行するクライアント側です。つまり、unibonさんが指摘しているように、ファイルサーバ上の MDB から処理に必要なデータ(インデックスかレコードか)を一旦、全てクライアント側に持ってきて、それに対して取捨選択や並べ替えなどを実行していた筈です。
また、別々のクライアントからの同時更新の可能性がある場合、「処理はどこで実行されるのか?」を考えると、怖くて使えないと思います。

Access
ぬし
会議室デビュー日: 2002/04/08
投稿数: 829
投稿日時: 2005-10-20 07:55
引用:

ツールの利用者は300人程度で、対して利用者がアクセスするデータは10000件ですが同時に使用する事がなく、規模的にこれくらいのシステムが良いと判断し作成しました。


Accessはファイル共有型のデータベースのためWebでの利用には慎重さが要求されます。利用者が300人で、データ件数が10,000件ということはMSDEなどにアップグレードされることをお勧めします。

どうしてもAccessを利用されるときは、利用者を数人(5人以下)でデータ件数も1000件ぐらいに限定したイントラネットの環境で利用されることをお勧めします。

以前、Access + ASPで大企業向けのイントラネットシステムを構築しましたが利用者を7人、データ件数を5000件以下に限定しています。レスポンスも問題なく正常に動作しております。排他制御は楽観的ロックを採用しております(ADO.NETのDataAdapterのUpdateメソッドで採用している方式)。
_________________
ASP.NET+Ajaxサンプル集

[ メッセージ編集済み 編集者: Access 編集日時 2005-10-20 07:58 ]
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-10-20 09:41
そんぐらい人数の規模だと、MDBはもう無理ですね。
MSDEもいいですが同時利用が5までのはずなので、使い物にならなくなってしまうでしょう。
SQL Serverを購入されデータベースを移行されるといいと思います。
予算がなければオープンソースのDBMSを利用してODBC経由で利用するという手もあります。
むさし
会議室デビュー日: 2003/07/07
投稿数: 8
投稿日時: 2005-10-20 10:41
こんにちは、むさしです。

unibonさん、きくちゃんさん、Accessさん、Anthyhimeさん早々にアドバイスありがとうございます。
こんなにアドバイスいただけるとおもっていませんでしたので正直感動しました。
少し電○男の気持ちがわかりました(笑

>unibonさん
回線速度はLANなので一応細いとこでも10Mbpsはあり直にAccessを開きADOで投げているSQLと同様の結果をクエリに書き込んで実行しても表示に2,3秒程度しかかかっていない
ようでした。
やはりクエリで表示するだけとでは大きくちがうものなのでしょうね・・・
ちなみに記述は以下のような感じです(単一レコード検索時)。CnはConnectionでツール起動時にPublicで宣言しています。

Try
Cn.Open()
Try
Dim cm As New OleDb.OleDbCommand("SELECT Name,Age FROM TBL1;", Cn)
Dim Dr As OleDb.OleDbDataReader = cm.ExecuteReader()
Try
Dr.Read()
Data.Name = Dr.GetValue(0)
Data.Age = Dr.GetValue(1)
Finally
Dr.Close()
End Try
Finally
Cn.Close()
End Try
Catch ex As Exception
MessageBox.ShowDialog("エラーです")
End Try

>きくちゃんさん
企画段階にてSQLServerも視野にいれたのですがもともとがAccessで作っていたシステムでMDBファイルを配布・回収して運用するというものでしたので元あった構成を流用出来ればと思ったことと、いきなり全くしらないSQLServerなどを利用してできるのか不安であり調べたところJetで同時に50人程度がアクセスするシステムを作成している方もいらして同じような構成でさらには2台の端末でループで10000件の更新作業を同時に行わせても短時間で完了し問題ないかとおもっていたのですが大誤算でした・・・
きくちゃんさんの「怖くて使えない」という言葉だけでも怖くなってきました・・・

>Accessさん
上記コードのようにConectionを生成したままで利用時にオープンさせるような場合瞬間的な接続になると解釈し300人のユーザーであったとしても瞬間的であれば問題なく更新についてもユーザーの利用するデータは担当が決まっているため同じレコードを更新することがないため問題となることがないと思ったのですがこれは間違いでしょうか?
Accessさんの提供されました5000件規模のものがうまくいっているというのが気になりますが倍になると一気に使い物にならなくなってしまうのでしょうか・・・
ただ単純に件数が10倍になったからといって時間も倍ではないという現状からみるとありえる話なのかなとも思えます。
一度別のDBについても視野に入れて検討してみたいとおもいます。

>Anthyhimeさん
MSDEの5人アクセスというのも常にDBへ要求をなげない状態でも5人というのが制限にあるのでしょうか?
予算の件はおっしゃるとおり決済をきったあとで修正が難しいものですのでオープンソースのDBMSというものも参考にさせていただき調べてみたいとおもいます。

普段利用していて10000件のデータなどよくAccessで利用していたので全然余裕かとおもっていましたがプログラムにて処理を行うとなると別物なのですね。
システムの奥の深さを痛感します・・・

[ メッセージ編集済み 編集者: むさし 編集日時 2005-10-20 10:56 ]

[ メッセージ編集済み 編集者: むさし 編集日時 2005-10-20 11:00 ]
Access
ぬし
会議室デビュー日: 2002/04/08
投稿数: 829
投稿日時: 2005-10-21 06:11
引用:

上記コードのようにConectionを生成したままで利用時にオープンさせるような場合瞬間的な接続になると解釈し300人のユーザーであったとしても瞬間的であれば問題なく更新についてもユーザーの利用するデータは担当が決まっているため同じレコードを更新することがないため問題となることがないと思ったのですがこれは間違いでしょうか?
Accessさんの提供されました5000件規模のものがうまくいっているというのが気になりますが倍になると一気に使い物にならなくなってしまうのでしょうか・・・


もちろんデータベースと接続する時間を最小限にするのが前提です。私のサイトでAccessのMDBを使用しているのですが、一日に1万件のアクセスがありますが正常に動作しております。作り方次第ということになります。最近、SQL Serverに移行したのですがレスポンスがかなりよくなりました。SQL Server 2000 Workgroup Editionはかなり安価(約8万円から)になりましたので検討されてはどうでしょうか。

同じレコードの更新がないなら排他制御は不要です。

データ件数ですが一定の限界を超えると極端にレスポンスが低下することがあるようです。それからLAN環境で使用するとき、Accessのデータがキャッシュされないバグがあります。このバグは、MDBが格納されているフォルダ名が漢字、8桁以上などのときに発生するようです。このバグを回避するとレスポンスがかなり向上します。

_________________
ASP.NET+Ajaxサンプル集

[ メッセージ編集済み 編集者: Access 編集日時 2005-10-21 06:16 ]
Beatle
ぬし
会議室デビュー日: 2003/06/09
投稿数: 394
投稿日時: 2005-10-21 08:39
ちゃちゃ入れですが...

引用:

Accessさんの書き込み (2005-10-21 06:11) より:

もちろんデータベースと接続する時間を最小限にするのが前提です。私のサイトでAccessのMDBを使用しているのですが、一日に1万件のアクセスがありますが正常に動作しております。作り方次第ということになります。最近、SQL Serverに移行したのですがレスポン



これはちょっと状況が違うと思いますよ。
元投稿者の環境は基本的にはC/Sで、SQL発行側とDB側が別となっているので、
物理的にn:1になるんですが、WEBの場合、MDBから見ればあくまでもWEB
サーバーからのアクセスしか無いわけですよね?ですから物理的には1:1になり
ます。
最近のACCESSでセッション管理がどうなっているか知りませんが、WEB
サーバーとMDBが同じサーバーにあれば、スタンドアロンでのMDBの共有化
(同時使用)ということだけなので、ACCESS内のクエリー、レポート等は使わず
単にMDBというファイルを利用しているだけなので動くのではないでしょうか?

スキルアップ/キャリアアップ(JOB@IT)