Q.Accessって1万件超えると遅くて使い物にならないって本当ですか?

 

本当とも言えますし、嘘だとも言えますね。

Accessに限らず、現在のPC上で動作するアプリケーションのすべてにおいて、一定のパフォーマンスを保証することは不可能です。
動作するハードウェア、ソフトウェア環境によって大きく違ってしまうため、ソフトウェア実行においてのベンチマークになんの意味もないからです。
つまり、「あるマシンで1時間かかった処理が違う環境では1秒かからない」ことも当然ありえる、いえありえるどころじゃない、現実としてあるのです。

よく「マイク○ソフトはベンチマーク結果を公表しないんですかっ!?」としたり顔で(実際は電話ですから顔は見えないんですけど)文句言ってくる人もいましたが、こんなこと言ってる人は素人ですから言うことをきいては駄目です。
PCというのは、ハードウェア環境がすべて一定に保証されている汎用機と違って、自作マシンもあればメーカー機もあり、AT互換機もあればPC98マシンもありと、ハードウェアの性能が一定じゃないんですから、処理時間なんて計ったって完全一致する環境があるワケがないんです。そんな信用できない情報を欲しがる人の気が知れません。
「じゃあ、一般的な環境でいいから・・・」一般的ってなんですか??一般的って??余計わかりませんよね。
マシン購入時には「標準スペック」とか気軽にいいますけど、これも「買う人の予算範囲内で納得できるスペック」って意味ですからぜんぜんアテにはなりませんよね。自分のまわりの人(会社の人?)が使っている環境=世間の標準と思ってるなんて、なんて幸せな人なんでしょう。
よく言われる「ベンチマークソフト」、あれはハードウェアの性能を計るためのもので、ソフトウェアのレスポンステストとは必ずしも一致しません。いくら浮動小数点演算能力が優れていても、HDDの読み込み・書き込みが遅ければやりたいことによっては遅くなることだってありますし。
すべての環境において保証できないベンチマークなど公表して何になるというのでしょう。「参考までに」聞いたところでどうしようというのですか。他の人のシステムも遅いと確認して安心したいのでしょうか。
原因を追求することもせず、遅いのを全部Accessのせいにして「Accessなんて使い物にならねぇぜ!」と堂々と言う奴には、
「使えねぇのはおまえだよ」
と、言ってやりましょう。(^^)にっこり

いや、確かに遅いんじゃないですかね、Oracle や SQL-Server と比べたら。(^^;)それは値段にもハッキリ現れていますよね。
最近はマイ○ロソフトが Oracle に負けまいと SQL Server のベンチマークを公表してるみたいですが、製造元が出したベンチマークなんて信じちゃ駄目です。
どんな都合のいい環境でどんな都合のいいデータを出したのかわかんないんですから。いくら他社製品と比較してたって、自社の環境での結果なんですから、いわゆる「広告用当社比」だと思っていいと思います。
ま、ベンチマーク出したら出したで、誰も信用してないんでいいと思いますけど(^^;)

たしかに、安定性や排他制御の点ではOracleに1歩どころか200歩ぐらい先にいかれている感のあるAccessですが(そもそも比べるな)、DB設計や使いようによってはそこそこのレスポンスも出るし、開発期間・準備期間は断然短いから導入費用は安くてすむし、バックアップさえしっかりとれば運用もラクだし、Accessならではのメリットもたくさんあるのです。
カネをかけりゃぁレスポンスアップできて当たり前です。安くて質の良い物を提供するのが技術者の心意気ってもんじゃぁないですか?!


と、いう訳で。
レスポンスアップしたい場合に、チェックするポイントは以下のとおりです。

  • なにをしている部分に一番時間がかかっているのか
    まず原因を突き止めることです。「決まってるじゃん、検索だよ検索」としか言わない上司、アナタ検索って意味わかってますか?
    Accessでの検索処理のやりかたには無限に方法があります。クエリーにまかせっきりの場合や、DAO で1件づつ判定して他テーブルに抽出している場合、複数のクエリーを実行して絞り込みを行っている場合。
    複数フェーズで実行している場合には各フェーズでしっかり時間を計測しましょう。
    3つのクエリーを実行していて、2つめだけが異常に遅いといった場合、そのクエリーの条件式を見直すだけで処理時間は100分の1、1000分の1にもなりえます。
    モジュール内で DAO を使っている場合、マイクロソフトのサポート情報にバッチ処理時のレスポンスアップのコツを記述した資料がありますので参考にしてください。

  • インデックスは適切かどうか
    1万件でも10万件でも、適切なインデックスがはられていて適切なデータ量単位で検索して使えばそれほど遅さは感じません。10万件から1件検索するのも、1件から1件検索するのも、インデックスを使用して検索する場合には速度の違いを体感することはほとんどないんです。
    データ量が増えて遅くなった場合、テーブル構造とインデックスに問題があります。よく検索に使用したり、他テーブルとの結合に使用する項目には「重複あり」でもいいですからインデックスをつけるようにしましょう。
    ただし、むやみにインデックスをつければいいってものでもありません。インデックスが多ければ更新に時間がかかるので必要最小限のインデックスを効果的に使うようにしましょう。
    適切なインデックス構築は、データベースソフトにおいて設計者のセンスと腕のみせどころです。

  • スワップしていないかどうか
    たぶん、1万件だの3万件だのを超えると突然遅くなるって言う人たちの場合、そこがスワップするかしないかの境目なのではないかと想像しています。(または、ただデータ量が多くなって処理時間を体感できるようになっただけなのに、大袈裟に遅くなったと騒いでいるだけ こういう人はレスポンスチェックなんてやったことがない素人です)
    スワップが起きるのと起きないのでは処理時間が雲泥の差です。見直せるものならハードウェア構成を見直す、余計な常駐アプリケーションを終了するなどしてみましょう。
    そうは言っても、通常はハード構成なんて変更できないですよね。こういう場合は、1度に処理する件数をフォームやレポートの仕様で制限してしまうのです。
    だいたい1画面に100件だの1000件だののレコードを一度に表示したって、たいがいの場合は該当レコードを探すだけでイヤになってしまいます。
    適切な検索条件を入力させて、画面に表示する前にデータを絞り込んでしまえばだいぶストレスを感じなくなります。

  • 頻繁におこるイベントで余計な処理を実行していないか
    フォーム上でカーソルが動くのが遅い!とイライラする場合、フォーカス喪失時やフォーカス取得時、レコード移動時などに指定している処理がいちいち動いてしまって余計な負荷をかけている場合もあります。
    たとえばコンボボックスの再クエリー。これはコンボボックスがフォーカス取得するたびにやっていたら、条件が複雑で処理時間がかかるクエリーの場合などはさすがに気になります。
    こういう処理はコンボボックスの絞込条件が変わらなければ再クエリーする必要はないんですから、絞込条件になるテキストボックスの更新後処理などでやるようにしましょう。
    最適なイベントで最適な処理をすることもレスポンスアップの重要なカギです。

  • ネットワークのレスポンス
    ネットワークが遅い場合。サーバーにMDBを置いて共有アクセスしていれば、当然ネットワーク負荷の影響をもろにかぶります。
    RASでログインしていて「Accessだから遅い」なんていわれちゃAccessも浮かばれません。
    こんなとき遅いのをAccessのせいにしてはいけません。このままのネットワーク環境Oracleに乗せかえる、なんて話がでてきちゃったらどうします?
    開発費用だけがかさんでレスポンスは全然あがらないってことになったら、信用問題どころが訴訟が起こりますよ。


ちょっと具体的な例をひとつ。
ODBC 経由で、某汎用機のデータベースの中身を参照し画面に一覧表示するというプログラムをAccessで作ったことがあります。
なにしろ相手は汎用機、データは4万件以上あり、さらにインデックスがはられていない!!いや単にODBCで利用できるインデックスが無かっただけかもしんないですけど
こんな状態なので、リンクテーブルをただ開くだけで、最初の文字が出るまでに約15秒かかっていました。
「遅いのはわかってるから、少しでも早くして」(--;;) ナンジャソレといわれて、試行錯誤を繰り返した結果、次のようなことがわかりました。

どうも「or」条件をつけると遅いのです。絞り込むため結果レコード数は少なくなるのですが、10件該当したとしても40秒以上かかっていました。
ところが「or」がつかない条件だと、結果は4万件あっても15秒程度で終わるのです。
ODBC トレースをとった結果、Where 条件式に「or」が入ると ODBC ドライバはお手上げするらしく、or条件以外の式を評価した結果のレコードセットをいったん作成し、Fetchして再度絞り込みを行っていました。

そこで、いったんor条件ぬきの条件式である程度絞り込んだ結果レコードセットを取り、それをそのまま自 MDB のワークテーブルに落とし込みました。つまりデータを複写しちゃったんですな。
そのあとor条件にあたる条件式で再度絞り込みを行い、再抽出するようにした結果、2度目の抽出は時間計測不可能な処理時間(つまり、1秒未満)で終わるため、どんな条件式を設定しても15秒で画面を表示できるようになりました。
普通であれば2度手間抽出したほうが速いなんてことは想像もしないでしょう。わたしもしませんでした(^^;;) 通常はなるべく1度の SQL で終わらせるのが良いとされていますし。

この例に限らず、「or条件式」が入る抽出は一般的に遅いです。同じ結果レコードセットなら、条件式が少ない方が処理時間は圧倒的に短くてすみます
Select * from A_Master
Where Key_Code = forms![MyForm]![KeyCode] or isnull(forms![MyForm]![KeyCode])
というクエリーと、
Select * from A_Master
というクエリーでは、たとえ結果が一緒でも処理速度は全然下の方が早いですから、isnull(forms![MyForm]![KeyCode])がTrueの状態のときには条件式をつけずに検索するのが一番速いのです。
レスポンスにこだわるのなら、何も考えずただクエリーを実行するよりは、状況に応じて SQL 文を構築して実行するぐらいのことはしなくてはダメだと言えるでしょう。

きちんと遅い原因を追求し明確にさえしてしまえば、このような手段をとることはそれほど難しくはないのです。
レスポンスアップはケースバイケース、経験がモノを言う匠の世界です。遅い遅いと文句ばかり言うだけではなく、遅い原因をさぐりレスポンスアップすることに生きがいを感じるぐらいのほうが骨のあるSE/プログラマだと思いますが、いかがでしょうか?

*そんなあなたにお勧め書籍*

データベースパフォーマンスアップの教科書 基本原理編

これマジデお勧め。検索エンジン経由でこの記事にたどりついた人はぜひ読むべき。
ちょっと高いけど金でこれだけの内容が手に入れば安いもんだ。

トラックバック(0)

トラックバックURL: http://www.naboki.net/movabletype/mt-tb.cgi/28