よつやTips

元IT技術者がおくる情シス超入門:VB.NET / SQLServer / 弥生製品

【ACCESS】クエリ実行時に「メモリ不足です」とエラーになる件

仕事でACCESSを使わざるを得ないという状況があって使ってるんですが、毎月そこそこデータ量が増えていくせいでついに、2GBを超えないにもかかわらずACCESSでSELECTの結果を返してくる前に「メモリ不足です」と怒られるようになってしまったので、対処をメモしておきます。

ACCESSの概要

たぶん、そこそこデータ量が多いんですよね。 4万~5万行×70フィールドくらいなんですけど、ACCESSだと多い方なんですかね。2GB 超えてないのと、ちょくちょく最適化は走らせてるのでそこまで重いということもないと思ってはいたのですが。

ツールの概要

・基幹システムからExcel形式でデータを取得(これが約4~5万行) ・ちょこちょこUPDATEで加工しながら、必要な資料作成のためにSELECTをバンバン実行する

というだけの、まぁ基本的なツールです。

実行環境

・Windows10Enterprise 64bit ・Intel Core i5-8400 2.80GHz2.81GHz ・メモリ8GBから16GBに増設したが駄目だった ・ACCESS 2016(Office Professioinal Plus 2016)

エラー発覚時に試したこと

いろいろ試してみて、やっぱりいまいち上手くいかなかったということと、忙しかったので急遽、緊急回避的にSQLServerに乗せ換えて乗り切ってしまいました。 それで年度末を乗り切っちゃうとデータがまた少なくなるので、最近になるまで放置してしまってました あたためてました。

・メモリを8GBから16GBに増設 → ダメでした ・MaxLocksPerFileの値を変更 → ダメでした ・他のPCを使ってみる → なんと、うまく動いてしまった…!  この時使ったのが、16GBメモリを乗せたCore i7windows7のマシンでした。  もう一つ、Windows10Enterpriseで、バージョン1909にアップデートしてない1809だったかと思います。  なぜこれらがうまくいったのか…いろいろ調べてみてもよくわからず…。。。

解決法①ACCESS.exeのプロセスのCPUマッピングを1つに限定する

調べてみた結果、メモリ不足と言われている割にCPUマッピングが原因ではないか?ということがわかりました。 参考: https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/d3042c09-2235-45d3-bc6b-b2434ab347c6/access?forum=officesupportteamja マイクロソフトの公式ドキュメントにあるの見逃してたのは内緒

Access はマルチスレッドで動作することを想定していないエンジンを利用しています。 この動作が影響してメモリ不足が生じる場合があります。

回避策 : 1. 現象が発生している Access ファイルを開きます。 2. [タスク マネージャー] を起動します。タスクマネージャの [プロセス] タブで “MSACCESS.EXE” のプロセスを右クリックします。 3. [関係の設定] メニューを選択します。 4. [プロセッサの関係] ダイアログ ボックスで、任意の一つの CPU のみチェックをオンにし、その他の CPU のチェックをオフにします。 5. OK でダイアログを閉じます。

これ~~~~~!これが知りたかった!!!!!!

MSのDoc:複数コアの CPU 環境で実行中の Access が応答なしになる 結局のところこれが原因のようでして、アクセスのデータベースエンジンがマルチコアCPUで正常に動かないことが原因のようで、手動でシングルにしてあげることで解消できるようです。

がしかし、問題点があり、この方法だと毎回、該当のAccessファイルを起動するたびに変更しなければならないという若干のめんどくささがあります。 これを回避するには、もしかすると特定のファイル、もしくはACCESSファイル起動時にシングルコアCPUで起動する、みたいな対処をすべきかもしれないのですが、どうやらもう一つ対処ができたようで、私はそちらを試しました。

解決法②SELECT句の修正

参考: https://blog.goo.ne.jp/itachi-yang/e/08f8919673e7b84615caf449133ed071

どうやら抽出時のクエリのWhere句にNULL許容のフィールドを対象に比較演算子を使った条件を使っていると、どうやら発生することがあるようです。 マルチコアCPUに戻してNZ関数でNULL置換をかけたうえで条件自体はそのままにしたところ、バンバン出てたエラーはなくなりました。 (NULL許可の項目自体についてはちょっといろいろあって修正ができないのです)

毎回CPUの設定を変更するというのも面倒ですし、クエリをさくっと修正して対応完了。

余談

そもそもACCESSをやめたいなァと思いSQLServerでクエリをまとめてみてはいますが、最終的に私以外がツールを触ることになる可能性も捨てきれないので当面はこのままいくのだろうなと思うとちょっと切ないです。 後任がVBA触れるとは限らない