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

*お勧め書籍:データベースのパフォーマンスに悩むあなたに
本当とも言えますし、嘘だとも言えますね。
Access に限らず、現在のすべてのコンピューター上で動作するアプリケーションにおいて、一定のパフォーマンスを保証することは不可能です。
動作するハードウェア、ソフトウェア環境によって大きく違ってしまうため、ソフトウェア実行においてのベンチマークになんの意味もないからです。
つまり、「あるマシンで1時間かかった処理が違う環境では1秒かからない」ことも当然ありえる、いえありえるどころじゃない、現実としてあるのです。
よく「マイク○ソフトはベンチマーク結果を公表しないんですかっ!?」としたり顔で(実際は電話ですから顔は見えないんですけど)文句言ってくる人もいましたが、こんなこと言ってる人は素人ですから言うことをきいては駄目です。
一般的なパソコン、サーバーというのは、ハードウェア環境がすべて一定に保証されている汎用機と違って、自作マシンもあればメーカー機もあり、AT 互換機もあれば PC98 マシンもありと (さすがにもうないだろそんなもの…歴史を感じるなあ) 、ハードウェアの性能が一定じゃないんですから、処理時間なんて計ったって完全一致する環境があるワケがないんです。そんな信用できない情報を欲しがる人の気が知れません。
「じゃあ、一般的な環境でいいから・・・」一般的ってなんですか??一般的って??余計わかりませんよね。
マシン購入時には「標準スペック」とか気軽にいいますけど、これも「買う人の予算範囲内で納得できるスペック」って意味ですからぜんぜんアテにはなりませんよね。自分のまわりの人(会社の人?)が使っている環境=世間の標準と思ってるなんて、なんて幸せな人なんでしょう。
よく言われる「ベンチマークソフト」、あれはほぼほぼハードウェアの性能を計るためのもので、ソフトウェアのパフォーマンステストとは必ずしも一致しません。いくら浮動小数点演算能力が優れていても、HDD の読み込み・書き込みが遅ければやりたいことによっては遅くなることだってありますし。
先日こんなご相談がありまして。(ここだけ最新クラウド環境での話)
Azure Database for PostgreSQL に対してよくわからないベンチマークを実行したお客様が、「プランをあげてもスコアが上がらない!!どういうことだ!!」
(プランをあげる=vCore の数とメモリを増やす という意味) と言っている、とのことでしたのでそのスコアとやらを見せてもらいました。
確かに、vCore の数が倍になろうと 4 倍になろうとスコアは全く変わっていませんでした。ただし、HyperScare に変更したらスコアは 20 倍ぐらいに上がっています。
で、よく見たら、実行してる SQL 文が Update と Insert なんですよ。1 万件だか 10 万件だか、同じような Update、Insert を 1 件ずつ淡々と実行するという。
…これ… ストレージの性能しか試してないよね…?
Azure Database for PostgreSQL では明記されてないですが、HyperScare はストレージが SSD と明記されてます。ということは、HyperScare じゃないプランは SSD ではないってことです。この差がスコアに出たってだけの話っすよね。
とまぁ、このように、ハードウェア環境が変わればデータベースのスループットは変わっちゃうんです。
自分が使う予定の環境とは違う環境で実行してるのが確実であるベンチマークなど公表してもらって何になるというのでしょう。「参考までに」聞いたところでどうしようというのですか。他の人のシステムも遅いと確認して安心したいのでしょうか。
原因を追求することもせず、遅いのを全部 Access のせいにして「Access なんて使い物にならねぇぜ!」と堂々と言う奴には、
「使えねぇのはおまえだよ」
と、言ってやりましょう。(^^)にっこり
いや、確かに遅いんじゃないですかね、Oracle や SQL Server と比べたら。(^^;)それは値段にもハッキリ現れていますよね。
最近はマイ○ロソフトが Oracle に負けまいと SQL Server のベンチマークを公表してるみたいですが、製造元が出したベンチマークなんて信じちゃ駄目です。
どんな都合のいい環境でどんな都合のいいデータを出したのかわかんないんですから。いくら他社製品と比較してたって、自社の環境での結果なんですから、いわゆる「広告用当社比」だと思っていいと思います。
ま、ベンチマーク出したら出したで、誰も信用してないんでいいと思いますけど(^^;)
たしかに、安定性や排他制御の点では Oracle に1歩どころか 200歩ぐらい先にいかれている感のある Access ですが(そもそも比べるな)、データベース設計や使いようによってはそこそこのパフォーマンス出るし、開発期間・準備期間は断然短いから導入費用は安くてすむし、バックアップさえしっかりとれば運用もラクだし、Access ならではのメリットもたくさんあるのです。
カネをかけりゃぁパフォーマンスアップできて当たり前です。安くて質の良い物を提供するのが技術者の心意気ってもんじゃぁないですか?!
と、いう訳で。
パフォーマンスアップしたい場合に、チェックするポイントは以下のとおりです。
なにをしている部分に一番時間がかかっているのか
まず原因を突き止めることです。「決まってるじゃん、検索だよ検索」としか言わない上司、アナタ検索って意味わかってますか?
Access での検索処理のやりかたには無限に方法があります。クエリーにまかせっきりの場合や、DAO で1件づつ判定して他テーブルに抽出している場合、複数のクエリーを実行して絞り込みを行っている場合。
複数フェーズで実行している場合には各フェーズでしっかり時間を計測しましょう。
3つのクエリーを実行していて、2つめだけが異常に遅いといった場合、そのクエリーの条件式を見直すだけで処理時間は 100 分の1、1000 分の1にもなりえます。
モジュール内で DAO を使っている場合、マイクロソフトのサポート情報にバッチ処理時のパフォーマンスアップのコツを記述した資料がありますので参考にしてください。
インデックスは適切か
1万件でも 10 万件でも、適切なインデックスがはられていて適切なデータ量単位で検索して使えばそれほど遅さは感じません。10 万件から1件検索するのも、1件から1件検索するのも、インデックスを使用して検索する場合には速度の違いを体感することはほとんどないんです。
データ量が増えて遅くなった場合、テーブル構造とインデックスに問題があります。よく検索に使用したり、他テーブルとの結合に使用する項目には「重複あり」でもいいですからインデックスをつけるようにしましょう。
ただし、むやみにインデックスをつければいいってものでもありません。インデックスが多ければ更新に時間がかかるので必要最小限のインデックスを効果的に使うようにしましょう。
適切なインデックス構築は、データベースソフトにおいて設計者のセンスと腕のみせどころです。
スワップしていないか
たぶん、1万件だの3万件だのを超えると突然遅くなるって言う人たちの場合、そこがスワップするかしないかの境目なのではないかと想像しています。(または、ただデータ量が多くなって処理時間を体感できるようになっただけなのに、大袈裟に遅くなったと騒いでいるだけ こういう人はパフォーマンスチェックなんてやったことがない素人です)
スワップが起きるのと起きないのでは処理時間が雲泥の差です。見直せるものならハードウェア構成を見直す、余計な常駐アプリケーションを終了するなどしてみましょう。
そうは言っても、通常はハード構成なんて変更できないですよね。こういう場合は、1度に処理する件数をフォームやレポートの仕様で制限してしまうのです。
だいたい1画面に 100 件だの 1000 件だののレコードを一度に表示したって、たいがいの場合は該当レコードを探すだけでイヤになってしまいます。
適切な検索条件を入力させて、画面に表示する前にデータを絞り込んでしまえばだいぶストレスを感じなくなります。
頻繁におこるイベントで余計な処理を実行していないか
フォーム上でカーソルが動くのが遅い!とイライラする場合、フォーカス喪失時やフォーカス取得時、レコード移動時などに指定している処理がいちいち動いてしまって余計な負荷をかけている場合もあります。
たとえばコンボボックスの再クエリー。これはコンボボックスがフォーカス取得するたびにやっていたら、条件が複雑で処理時間がかかるクエリーの場合などはさすがに気になります。
こういう処理はコンボボックスの絞込条件が変わらなければ再クエリーする必要はないんですから、絞込条件になるテキストボックスの更新後処理などでやるようにしましょう。
最適なイベントで最適な処理をすることもレスポンスアップの重要なカギです。
ネットワークのパフォーマンス
ネットワークが遅い場合。サーバーに mdb を置いて共有アクセスしていれば、当然ネットワーク負荷の影響をもろにかぶります。
ダイヤルアップ接続でログインしていて「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 文を構築して実行するぐらいのことはしなくてはダメだと言えるでしょう。
きちんと遅い原因を追求し明確にさえしてしまえば、このような手段をとることはそれほど難しくはないのです。
パフォーマンスアップはケースバイケース、経験がモノを言う匠の世界です。遅い遅いと文句ばかり言うだけではなく、遅い原因をさぐりパフォーマンスアップすることに生きがいを感じるぐらいのほうが骨のあるエンジニアだと思いますが、いかがでしょうか?